教程:在 Azure 应用服务中托管启用了 CORS 的 RESTful APITutorial: Host a RESTful API with CORS in Azure App Service

Azure 应用服务提供高度可缩放、自修补的 Web 托管服务。Azure App Service provides a highly scalable, self-patching web hosting service. 另外,应用服务还为 RESTful API 提供对跨域资源共享 (CORS) 的内置支持。In addition, App Service has built-in support for Cross-Origin Resource Sharing (CORS) for RESTful APIs. 本教程介绍如何将 ASP.NET Core API 应用部署到提供 CORS 支持的应用服务。This tutorial shows how to deploy an ASP.NET Core API app to App Service with CORS support. 请使用命令行工具来配置应用,使用 Git 来部署应用。You configure the app using command-line tools and deploy the app using Git.

本教程介绍如何执行下列操作:In this tutorial, you learn how to:

  • 使用 Azure CLI 创建应用服务资源Create App Service resources using Azure CLI
  • 使用 Git 将 RESTful API 部署到 AzureDeploy a RESTful API to Azure using Git
  • 启用应用服务 CORS 支持Enable App Service CORS support

可以在 macOS、Linux、Windows 中执行本教程中的步骤。You can follow the steps in this tutorial on macOS, Linux, Windows.

如果没有 Azure 订阅,可在开始前创建一个试用帐户If you don't have an Azure subscription, create a trial account before you begin.


完成本教程:To complete this tutorial:

创建本地 ASP.NET Core 应用Create local ASP.NET Core app

在此步骤中,请设置本地 ASP.NET Core 项目。In this step, you set up the local ASP.NET Core project. 应用服务支持以其他语言编写的适用于 API 的同一工作流。App Service supports the same workflow for APIs written in other languages.

克隆示例应用程序Clone the sample application

在终端窗口中,通过 cd 转到工作目录。In the terminal window, cd to a working directory.

运行下列命令,克隆示例存储库。Run the following command to clone the sample repository.

git clone https://github.com/Azure-Samples/dotnet-core-api

此存储库包含基于以下教程创建的应用:使用 Swagger 的 ASP.NET Core Web API 帮助页This repository contains an app that's created based on the following tutorial: ASP.NET Core Web API help pages using Swagger. 它使用 Swagger 生成器来提供 Swagger UI 和 Swagger JSON 终结点。It uses a Swagger generator to serve the Swagger UI and the Swagger JSON endpoint.

运行应用程序Run the application

运行以下命令,安装所需的包,运行数据库迁移并启动应用程序。Run the following commands to install the required packages, run database migrations, and start the application.

cd dotnet-core-api
dotnet restore
dotnet run

在浏览器中导航到 http://localhost:5000/swagger,以便使用 Swagger UI。Navigate to http://localhost:5000/swagger in a browser to play with the Swagger UI.

在本地运行的 ASP.NET Core API

导航到 http://localhost:5000/api/todo,此时会看到 ToDo JSON 项的列表。Navigate to http://localhost:5000/api/todo and see a list of ToDo JSON items.

导航到 http://localhost:5000 并使用浏览器应用。Navigate to http://localhost:5000 and play with the browser app. 稍后请将浏览器应用指向应用服务中的远程 API,以便测试 CORS 功能。Later, you will point the browser app to a remote API in App Service to test CORS functionality. 浏览器应用的代码位于存储库的 wwwroot 目录中。Code for the browser app is found in the repository's wwwroot directory.

在终端按 Ctrl+C 可随时停止 ASP.NET Core。To stop ASP.NET Core at any time, press Ctrl+C in the terminal.

将应用部署到 AzureDeploy app to Azure

在此步骤中,将已连接 SQL 数据库的 .NET Core 应用程序部署到应用服务。In this step, you deploy your SQL Database-connected .NET Core application to App Service.

配置本地 Git 部署Configure local git deployment

使用 az webapp deployment user set 命令配置部署凭据。Configure deployment credentials with the az webapp deployment user set command. 对 Web 应用进行 FTP 和本地 Git 部署时需要此部署用户。This deployment user is required for FTP and local Git deployment to a web app. 用户名和密码都为帐户级别。The user name and password are account level. 它们与 Azure 订阅凭据不同。They are different from your Azure subscription credentials.

在以下示例中,将 <username><password>(包括括号)替换为新的用户名和密码。In the following example, replace <username> and <password> (including brackets) with a new user name and password. 用户名在 Azure 中必须唯一。The user name must be unique within Azure. 密码长度必须至少为 8 个字符,其中包含以下 3 种元素中的两种:字母、数字、符号。The password must be at least eight characters long, with two of the following three elements: letters, numbers, symbols.

az webapp deployment user set --user-name <username> --password <password>

命令执行完成后你会获得一个 JSON 输出,密码显示为 nullYou should get a JSON output, with the password shown as null. 如果收到 'Conflict'. Details: 409 错误,请更改用户名。If you get a 'Conflict'. Details: 409 error, change the username. 如果收到 'Bad Request'. Details: 400 错误,请使用更强的密码。If you get a 'Bad Request'. Details: 400 error, use a stronger password.

只需配置此部署用户一次;之后可对所有 Azure 部署使用此用户。You need to configure this deployment user only once; you can use it for all your Azure deployments.


记录用户名和密码。Record the user name and password. 稍后需要使用它们来部署 Web 应用。You need them to deploy the web app later.

创建资源组Create a resource group

资源组是在其中部署和管理 Azure 资源(例如 Web 应用、数据库和存储帐户)的逻辑容器。A resource group is a logical container into which Azure resources like web apps, databases, and storage accounts are deployed and managed.

使用 az group create 命令创建资源组。Create a resource group with the az group create command. 以下示例在“中国北部”位置创建名为“myResourceGroup”的资源组。The following example creates a resource group named myResourceGroup in the China North location. 要查看“免费”层中应用服务支持的所有位置,请运行 az appservice list-locations --sku F1 命令。To see all supported locations for App Service in Free tier, run the az appservice list-locations --sku F1 command.

az group create --name myResourceGroup --location "China North"

通常在附近的区域中创建资源组和资源。You generally create your resource group and the resources in a region near you.

此命令完成后,JSON 输出会显示资源组属性。When the command finishes, a JSON output shows you the resource group properties.

创建应用服务计划Create an App Service plan

使用 az appservice plan create 命令创建应用服务计划。Create an App Service plan with the az appservice plan create command.

应用服务计划指定托管应用的 Web 服务器场的位置、大小和功能。An App Service plan specifies the location, size, and features of the web server farm that hosts your app. 可以在托管多个应用时节省资金,方法是将多个 Web 应用配置为共用单个应用服务计划。You can save money when hosting multiple apps by configuring the web apps to share a single App Service plan.

应用服务计划定义:App Service plans define:

  • 区域(例如:中国东部、中国东部 2、中国北部、中国北部 2)Region (for example: China East, China East 2, China North, China North 2)
  • 实例大小(小、中、大)Instance size (small, medium, or large)
  • 规模计数(1 到 20 个实例)Scale count (1 to 20 instances)
  • SKU(免费、共享、基本、标准、高级)SKU (Free, Shared, Basic, Standard, or Premium)

以下示例在免费定价层中创建名为 myAppServicePlan 的应用服务计划:The following example creates an App Service plan named myAppServicePlan in the Free pricing tier:

az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE

创建应用服务计划后,Azure CLI 将显示类似于以下示例的信息:When the App Service plan has been created, the Azure CLI shows information similar to the following example:

  "adminSiteName": null,
  "appServicePlanName": "myAppServicePlan",
  "geoRegion": "China North",
  "hostingEnvironmentProfile": null,
  "id": "/subscriptions/0000-0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
  "kind": "app",
  "location": "China North",
  "maximumNumberOfWorkers": 1,
  "name": "myAppServicePlan",
  < JSON data removed for brevity. >
  "targetWorkerSizeId": 0,
  "type": "Microsoft.Web/serverfarms",
  "workerTierName": null

创建 Web 应用Create a web app

myAppServicePlan 应用服务计划中创建一个 Web 应用。Create a web app in the myAppServicePlan App Service plan.

可以使用 az webapp create 命令。You can use the az webapp create command. 在以下示例中,将 <app_name> 替换为全局唯一的应用名称(有效字符是 a-z0-9-)。In the following example, replace <app_name> with a globally unique app name (valid characters are a-z, 0-9, and -).

az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name <app_name> --deployment-local-git

创建 Web 应用后,Azure CLI 会显示类似于以下示例的输出:When the web app has been created, the Azure CLI shows output similar to the following example:

Local git is configured with url of 'https://<username>@<app_name>.scm.chinacloudsites.cn/<app_name>.git'
  "availabilityState": "Normal",
  "clientAffinityEnabled": true,
  "clientCertEnabled": false,
  "cloningInfo": null,
  "containerSize": 0,
  "dailyMemoryTimeQuota": 0,
  "defaultHostName": "<app_name>.chinacloudsites.cn",
  "deploymentLocalGitUrl": "https://<username>@<app_name>.scm.chinacloudsites.cn/<app_name>.git",
  "enabled": true,
  < JSON data removed for brevity. >


Git 远程的 URL 将显示在 deploymentLocalGitUrl 属性中,其格式为 https://<username>@<app_name>.scm.chinacloudsites.cn/<app_name>.gitThe URL of the Git remote is shown in the deploymentLocalGitUrl property, with the format https://<username>@<app_name>.scm.chinacloudsites.cn/<app_name>.git. 保存此 URL,因为稍后需要它。Save this URL as you need it later.

从 Git 推送到 AzurePush to Azure from Git

回到本地终端窗口,将 Azure 远程功能添加到本地 Git 存储库。Back in the local terminal window, add an Azure remote to your local Git repository. <deploymentLocalGitUrl-from-create-step> 替换为在创建 Web 应用中保存的 Git 远程 URL。Replace <deploymentLocalGitUrl-from-create-step> with the URL of the Git remote that you saved from Create a web app.

git remote add azure <deploymentLocalGitUrl-from-create-step>

使用以下命令推送到 Azure 远程功能以部署应用。Push to the Azure remote to deploy your app with the following command. 当 Git 凭据管理器提示输入凭据时,请确保输入在配置部署用户中创建的凭据,而不是用于登录到 Azure 门户的凭据。When prompted for credentials by Git Credential Manager, make sure that you enter the credentials you created in Configure a deployment user, not the credentials you use to sign in to the Azure portal.

git push azure master

此命令可能需要花费几分钟时间运行。This command may take a few minutes to run. 运行时,该命令会显示类似于以下示例的信息:While running, it displays information similar to the following example:

Counting objects: 98, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (92/92), done.
Writing objects: 100% (98/98), 524.98 KiB | 5.58 MiB/s, done.
Total 98 (delta 8), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: .
remote: Updating submodules.
remote: Preparing deployment for commit id '0c497633b8'.
remote: Generating deployment script.
remote: Project file path: ./DotNetCoreSqlDb.csproj
remote: Generated deployment script files
remote: Running deployment command...
remote: Handling ASP.NET Core Web Application deployment.
remote: .
remote: .
remote: .
remote: Finished successfully.
remote: Running post deployment command(s)...
remote: Deployment successful.
remote: App container will begin restart within 10 seconds.
To https://<app_name>.scm.chinacloudsites.cn/<app_name>.git
 * [new branch]      master -> master

浏览到 Azure 应用Browse to the Azure app

在浏览器中导航到 http://<app_name>.chinacloudsites.cn/swagger,开始使用 Swagger UI。Navigate to http://<app_name>.chinacloudsites.cn/swagger in a browser and play with the Swagger UI.

在 Azure 应用服务中运行的 ASP.NET Core API

导航到 http://<app_name>.chinacloudsites.cn/swagger/v1/swagger.json 即可看到已部署 API 的 swagger.jsonNavigate to http://<app_name>.chinacloudsites.cn/swagger/v1/swagger.json to see the swagger.json for your deployed API.

导航到 http://<app_name>.chinacloudsites.cn/api/todo 即可看到已部署 API 正在运行。Navigate to http://<app_name>.chinacloudsites.cn/api/todo to see your deployed API working.

添加 CORS 功能Add CORS functionality

接下来,在适用于 API 的应用服务中启用内置的 CORS 支持。Next, you enable the built-in CORS support in App Service for your API.

在示例应用中测试 CORSTest CORS in sample app

在本地存储库中,打开 wwwroot/index.htmlIn your local repository, open wwwroot/index.html.

在第 51 中,将 apiEndpoint 变量设置为已部署 API 的 URL (http://<app_name>.chinacloudsites.cn)。In Line 51, set the apiEndpoint variable to the URL of your deployed API (http://<app_name>.chinacloudsites.cn). 在应用服务中将 <appname> 替换为你的应用名称。Replace <appname> with your app name in App Service.

在本地终端窗口中,再次运行示例应用。In your local terminal window, run the sample app again.

dotnet run

导航到浏览器应用 (http://localhost:5000)。Navigate to the browser app at http://localhost:5000. 在浏览器中打开开发人员工具窗口(在用于 Windows 的 Chrome 中使用 Ctrl+Shift+i),检查“控制台”选项卡。此时会看到错误消息:No 'Access-Control-Allow-Origin' header is present on the requested resourceOpen the developer tools window in your browser (Ctrl+Shift+i in Chrome for Windows) and inspect the Console tab. You should now see the error message, No 'Access-Control-Allow-Origin' header is present on the requested resource.

浏览器客户端中的 CORS 错误

由于浏览器应用 (http://localhost:5000) 和远程资源 (http://<app_name>.chinacloudsites.cn) 的域不匹配,并且由于应用服务中的 API 未发送 Access-Control-Allow-Origin 标头,因此浏览器已阻止跨域内容在浏览器应用中加载。Because of the domain mismatch between the browser app (http://localhost:5000) and remote resource (http://<app_name>.chinacloudsites.cn), and the fact that your API in App Service is not sending the Access-Control-Allow-Origin header, your browser has prevented cross-domain content from loading in your browser app.

在生产中,浏览器应用会有一个公共 URL 而不是 localhost URL,但对 localhost URL 启用 CORS 的方式与对公共 URL 相同。In production, your browser app would have a public URL instead of the localhost URL, but the way to enable CORS to a localhost URL is the same as a public URL.

启用 CORSEnable CORS

使用 az resource update 命令对客户端的 URL 启用 CORS。Enable CORS to your client's URL by using the az resource update command. 替换 <appname> 占位符。Replace the <appname> placeholder.

az resource update --name web --resource-group myResourceGroup --namespace Microsoft.Web --resource-type config --parent sites/<app_name> --set properties.cors.allowedOrigins="['http://localhost:5000']" --api-version 2015-06-01

可以在 properties.cors.allowedOrigins ("['URL1','URL2',...]") 中设置多个客户端 URL。You can set more than one client URL in properties.cors.allowedOrigins ("['URL1','URL2',...]"). 也可使用 "['*']" 启用所有客户端 URL。You can also enable all client URLs with "['*']".

再次测试 CORSTest CORS again

刷新浏览器应用 (http://localhost:5000)。Refresh the browser app at http://localhost:5000. “控制台”窗口中的错误消息现在已消失,可以看到已部署 API 中的数据并与之交互。The error message in the Console window is now gone, and you can see the data from the deployed API and interact with it. 远程 API 现在支持对本地运行的浏览器应用使用 CORS。Your remote API now supports CORS to your browser app running locally.

CORS 在浏览器客户端中成功

恭喜!你在包含 CORS 支持的 Azure 应用服务中运行了 API。Congratulations, you're running an API in Azure App Service with CORS support.

应用服务 CORS 与你的 CORS 的比较App Service CORS vs. your CORS

为了提高灵活性,可以使用自己的 CORS 实用程序而不是应用服务 CORS。You can use your own CORS utilities instead of App Service CORS for more flexibility. 例如,可能需要针对不同的路由或方法指定不同的允许的源。For example, you may want to specify different allowed origins for different routes or methods. 由于应用服务 CORS 允许你为所有 API 路由和方法指定一组接受的源,因此你需要使用自己的 CORS 代码。Since App Service CORS lets you specify one set of accepted origins for all API routes and methods, you would want to use your own CORS code. 请参阅启用跨域请求 (CORS),了解 ASP.NET Core 如何这样做。See how ASP.NET Core does it at Enabling Cross-Origin Requests (CORS).


请勿尝试将应用服务 CORS 与你自己的 CORS 代码一起使用。Don't try to use App Service CORS and your own CORS code together. 一起使用时,应用服务 CORS 优先级高,你自己的 CORS 代码将无效。When used together, App Service CORS takes precedence and your own CORS code has no effect.

清理资源Clean up resources

若要清理资源,请运行以下命令:To clean up your resources, run the following command:

az group delete --name myResourceGroup

后续步骤Next steps

现已了解:What you learned:

  • 使用 Azure CLI 创建应用服务资源Create App Service resources using Azure CLI
  • 使用 Git 将 RESTful API 部署到 AzureDeploy a RESTful API to Azure using Git
  • 启用应用服务 CORS 支持Enable App Service CORS support

转到下一教程,了解如何对用户进行身份验证和授权。Advance to the next tutorial to learn how to authenticate and authorize users.