介绍

CO卡宴S 是W3C(World Wide Web Consortium
万维网缔盟,请留心不是复仇者联盟)
的2个正规,意在让JavaScript克制浏览器强加的同源策略安全限制。
同源策略意味着你的JavaScript只好使AJAX回调到含有网页的等同原点(当中“origin”被定义为主机名,协议和端口号的重组)。
例如,来自
http://localhost
的Web页面上的JavaScript无法将AJAX调用到
http://wwww.micorosoft.com
(或
http://www.localhost:8086
)上的能源。

**
简单的讲,就是W3C先把您的手绑起来,然后再想个办法开个后门给你松松绑,就像是此。那都以他们整出来黑小编大代码党的幺蛾子。**

CORubiconS通过让服务器标注哪些财富允许被跨域调用,来放松那几个限制。
COENCORES由浏览器执行,但必须在服务器上贯彻,最新版本的ASP.NET Web API
2具有全部的CO大切诺基S帮衬。 使用Web API
2,您能够配备策略以允许来自差别来源的JavaScript客户端访问您的API。

更详实的普通话资料能够看
这儿

怎么是同源

借使多少个U途观L他们有一样的域名,端口号,那八个U科雷傲L就是有一样的源.即:同源

上边是同源的多少个U汉兰达L

  • 1 http://example.com/foo.htm
  • 2 http://example.com/bar.html
    下边多少个USportageL相比较上边七个U大切诺基L是不一样源的
  • 1 http://example.net
  • 2 http://example.com:9000/foo.html
  • 3 https://example.com/foo.html
  • 4 https://www.example.com/foo.html

正文

首先,假若你明白怎么使用C#编写WebAPI,就算不懂,能够看看
十分钟急忙完结WebAPI
其次,固然你掌握怎么采用Postman, 精晓写前端页面,也许明白写ASP.NET
MVC,总而言之,你掌握写一丝丝JS代码。 不懂的话,能够先看看 [Vue.JS 单页应用

  • 联系人管理(一)](https://www.jianshu.com/p/e474a8fb6cb1)
    这些类别,洗洗脑先。
    比方你八个都不懂,作者比较奇怪你是怎么点进去的?!
    您左右端都懂了,笔者就不管说些有的没的。
  1. XMLHttpRequest cannot load XXXX. Cross origin requests are only
    supported for protocol schemes: http, data, chrome,
    chrome-extension, https, chrome-extension-resource.

    本条荒唐平时是因为你直接行使文件管理器打开的HTML文件,而FILE协议默许并不在协理中。只要你通过HTTP协议访问就能够幸免那些标题了。
    即使你真正想,极度想本地也能,咋做吧,照旧有点子的…
    **
    给浏览器传入运转参数(allow-file-access-from-files),允许跨域访问。**
    Windows下,运营(CMD+Tucson)或创制火速格局:
    “C:\Program Files (x86)\Google\Chrome\Application\chrome.exe”
    –allow-file-access-from-files
  2. Origin xxxx is not allowed by Access-Control-Allow-Origin
    不当看起来像下图,

    皇冠官方网站 1

    不允许域xxxx的请求

这个错误,说的是你发出请求的域,没有在服务器允许的范围之内。解决方法是修改web.config,找到这样的地方,没有就添加,有的话,就看看有啥不同,简单的说就是找不同,大家来找茬。

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <!-- Adding the following custom HttpHeader 
                 will help prevent CORS from stopping the Request-->
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

入门的时候,你就那样写,反正死不了,高手的话,反正也不需求小编说,应该明了,哪里该花点心理。

  1. Web.config中的配置参数表

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
</system.webServer>

能够遵照须求,调整本人同意的Origin, Headers以及Mothods。

  1. EnableCorsAttribute **
    EnableCorsAttribute
    类用于配置CO途达S策略,接受三个或八个参数,那个参数分别为:
    ** 允许的域列表 **
    ** 允许的呼吁头列表

    ** 允许的伸手方法列表**
    允许的响应头列表(可选)
    代码看起来像上边那样

public class ResourcesController : ApiController
{
  [EnableCors("http://localhost:55912", // Origin
              null,                     // Request headers
              "GET",                    // HTTP methods
              "bar",                    // Response headers
              SupportsCredentials=true  // Allow credentials
  )]
  public HttpResponseMessage Get(int id)
  {
    var resp = Request.CreateResponse(HttpStatusCode.NoContent);
    resp.Headers.Add("bar", "a bar value");
    return resp;
  }
  [EnableCors("http://localhost:55912",       // Origin
              "Accept, Origin, Content-Type", // Request headers
              "PUT",                          // HTTP methods
              PreflightMaxAge=600             // Preflight cache duration
  )]
  public HttpResponseMessage Put(Resource data)
  {
    return Request.CreateResponse(HttpStatusCode.OK, data);
  }
  [EnableCors("http://localhost:55912",       // Origin
              "Accept, Origin, Content-Type", // Request headers
              "POST",                         // HTTP methods
              PreflightMaxAge=600             // Preflight cache duration
  )]
  public HttpResponseMessage Post(Resource data)
  {
    return Request.CreateResponse(HttpStatusCode.OK, data);
  }
}

[EnableCors]参数methods介绍

[EnableCors]特色的methods,钦点了哪二个HTTP方法能够访问能源。为了使拥有办法都得以访问,使用通配符“
* ”。上面是三个只允许GET和POST方法的哀通知例:

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "get,post")]
public class TestController : ApiController
{
    public HttpResponseMessage Get() { ... }
    public HttpResponseMessage Post() { ... }
    public HttpResponseMessage Put() { ... }    
}

前言

如何是COLANDS,看起来怎么有点像CQRubiconS?
COKugaS是克罗丝-Origin Resource
Sharing(跨域能源共享)的简称,简称的机要指标是为了呈现宏大上还要令人猜疑。
现实定义和介绍能够看
W3C的文档
CQ凯雷德S的完备是Command Query Responsibility
Seperation(命令查询任务分开),与本文非亲非故。

[EnableCors]设置

你能够启用 CO奥迪Q7S在每贰个 action,controller,或Web API全局控制器中。

  • 1 action设置
    在action上同意跨域,设置[EnableCors]品质的action方法。上面包车型大巴例证使GetItemmethod
    单独允许跨域

public class ItemsController : ApiController
{
    public HttpResponseMessage GetAll() { ... }

    [EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
    public HttpResponseMessage GetItem(int id) { ... }

    public HttpResponseMessage Post() { ... }
    public HttpResponseMessage PutItem(int id) { ... }
}
  • 2 controller设置
    若是你设置EnableCors在控制器,它适用于该控制器上的持有的action。若是想对某3个action禁止使用跨域,请使用[DisableCors]脾性。上边包车型客车例子除了PutItem
    action 别的action都扶助跨域。

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
public class ItemsController : ApiController
{
    public HttpResponseMessage GetAll() { ... }
    public HttpResponseMessage GetItem(int id) { ... }
    public HttpResponseMessage Post() { ... }

    [DisableCors]
    public HttpResponseMessage PutItem(int id) { ... }
}
  • 3 全局设置
    在应用程序中为具有Web API
    控制器允许跨域,将三个EnableCorsAttribute实例传递给EnableCors方法:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("www.example.com", "*", "*");
        config.EnableCors(cors);
        // ...
    }
}

假若您在四个范围内多个设置[EnableCors]、优先顺序是:
1Action
2Controller
3Global

COHavalS工作原理

本节描述了在Http协议正式上http跨域请求中到底发生了怎么样。主要的是要精晓CO卡宴S是怎么做事的,那样你就足以正确配置[EnableCors]属性,和借使CO汉兰达S不像你预期的那样行事怎么排除错误。
CO科雷傲S为了允许使跨源请求引入了多少个新的HTTP头。要是浏览器帮忙COEvoqueS,它自动安装那些请求头,你不需求在您的JavaScript代码做其余改动。

那是一个跨域请求的例子。Origin请求头提供了产生这几个跨域请求的网站域名。

皇冠官方网站 2

恳请报文

若是服务器允许那几个跨域请求,响应报文中机动设置Access-Control-Allow-Origin头。那一个头的值分外请求报文中Origin头的值,可能是通配符“*”,那意味着任何来自是被允许的。

皇冠官方网站 3

一呼百应报文

固然响应不包含Access-Control-Allow-Origin头,那是AJAX请求退步。具体来说是浏览器区别意请求。即使服务器重回三个成功的响应,浏览器响应的结果不可用于客户端应用程序。

允许CORS

当今让我们在WebService应用CO冠道S。首先,添加CO奇骏SNuGet包。在Visual
Studio中,从“工具”菜单上,选取库软件包管理器,然后选择包管理器控制台。在包管理器控制台窗口中,键入以下命令:
nstall-Package Microsoft.AspNet.WebApi.Cors
那一个命令安装新型的包和翻新具有重视项,包含大旨Web API库。User
version标志针对四个一定的本子。 COLacrosseS包供给Web API 2.0或更高版本。
开辟文件App_Start /
WebApiConfig.cs。将上面包车型地铁代码添加到WebApiConfig.Register方法。

using System.Web.Http;
namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

接下来,TestController类添加EnableCors属性:

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebService.Controllers
{
    [EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}

origins参数,使用WebClient应用程序安排时用用的的UMuranoI,那允许跨域源来自WebClient的乞请,同时还不准全数其它跨域请求。之后,笔者将详细描述[EnableCors]的参数。

备注:U卡宴I与UHavalL不一致,U中华VI :Uniform Resource
Identifier,统一财富标识符
U本田CR-VL:Uniform Resource Locator,统一财富一定符
URubiconI以scheme和冒号开端。Scheme用小写/小写字母开端,前边为空只怕跟着更加多的大写/小写字母、数字、加号、减号和点号。冒号把scheme与scheme-specific-part分开了,并且scheme-specific-part的语法和语义(意思)由U凯雷德I的名字空间决定。如下边包车型客车例证:
http://域名,其中http是scheme,//域名
是scheme-specific-part,并且它的scheme与scheme-specific-part被冒号分开了。

重新布置更新WebService的应用程序。你不供给革新WebClient。现在WebClient的AJAX请求应该成功。GET、PUT和POST方法都是允许的。

皇冠官方网站 4

image.png

本文翻译自Enabling Cross-Origin Requests in ASP.NET Web API
2

浏览器安全防备web页面发出AJAX请求到另三个领域。那种范围称为同源策略,那是为着避防恶意网站读取敏感数据。不过,有时候。您恐怕想要让任何网航站调度室用您的web
API。
克罗丝 Origin Resource
Sharing(CO途达S)是一种W3C标准,允许服务器放松同源策略。CROS,服务器能够允许一部分跨域源而拒绝其余域的央浼。COGL450S比此前JSONP等技能更安全、更灵活。本学科体现了什么在Web
API的应用程序中启用CROS。

[EnableCors]参数origin介绍

[EnableCors]的origins
参数钦命了哪三个呼吁源点是同意访问的。允许的值期间是1个以逗号分隔的。

[EnableCors(origins: "http://www.contoso.com,http://www.example.com", 
    headers: "*", methods: "*")]

创建WebClient 项目

皇冠官方网站 5

image.png

在缓解方案能源管理器,打开文件/ Home / Index.cshtml
。用以下代码替换该文件中的代码:

<div>
    <select id="method">
        <option value="get">GET</option>
        <option value="post">POST</option>
        <option value="put">PUT</option>
    </select>
    <input type="button" value="Try it" onclick="sendRequest()" />
    (Result)
</div>

@section scripts {
<script>
    // TODO: Replace with the URL of your WebService app
    var serviceUrl = 'http://mywebservice/api/test'; 

    function sendRequest() {
        var method = $('#method').val();

        $.ajax({
            type: method,
            url: serviceUrl
        }).done(function (data) {
            $('#value1').text(data);
        }).error(function (jqXHR, textStatus, errorThrown) {
            $('#value1').text(jqXHR.responseText || textStatus);
        });
    }
</script>
}

备注:serviceUrl变量,使用WebService项指标UOdysseyI。现在在该地运行WebClient应用程序或发表到另3个网站。

点击”Try
It”按钮提交1个AJAX请求到WebService应用程序,使用下拉框中列出的HTTP方法(GET、POST、大概put)。那让大家检查区别跨源请求。今后,
WebService应用程序不帮助COEvoqueS,所以只要您单击按钮,你会博得一个不当。

皇冠官方网站 6

image.png

自定义[EnableCors]特性

[EnableCors]特色达成了ICorsPolicyProvider接口。您能够提供自身的达成通过创设2个类,它来继承Attribute和落实了ICorsProlicyProvider接口。

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class MyCorsPolicyAttribute : Attribute, ICorsPolicyProvider 
{
    private CorsPolicy _policy;

    public MyCorsPolicyAttribute()
    {
        // Create a CORS policy.
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true
        };

        // Add allowed origins.
        _policy.Origins.Add("http://myclient.azurewebsites.net");
        _policy.Origins.Add("http://www.contoso.com");
    }

    public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request)
    {
        return Task.FromResult(_policy);
    }
}

现行反革命你能够在您想要允许跨域的任啥地方方采用你刚才自定义的[EnableCors].特性

[MyCorsPolicy]
public class TestController : ApiController
{
    .. //
}

CORAV4S 预检请求preflight request

对于有个别CO卡宴S请求,浏览器会发送2个附加的伸手,称为预检请求“preflight
request”,在出殡和埋葬的其实请求的财富在此以前。
浏览器能够跳过preflight request假如下列条件确实:

  • 1 央求的艺术是GET, HEAD, or POST,等
  • 2 应用程序不设置任何请求头除了Accept, Accept-Language,
    Content-Language, Content-Type, or Last-伊夫nt-ID等
  • 3 content – type报头(假若设置)是下列之一:
    application/x-www-form-urlencoded
    multipart/form-data
    text/plain
    那些请求头的正儿八经适用于当应用程序调用setRequestHeade
    XMLHttpRequest对象时发起的央浼头。
    规范并不适用于浏览器的乞请头能够设置,如用户代理,主机,或内容长度。

上面是preflight request的1个例子

皇冠官方网站 7

image.png

pre-flight请求使用HTTP OPTIONS方法。它归纳三个特出的伸手头:
Access-Control-Request-Method:HTTP方法将被用于实际的央求。
Access-Control-Request-Headers:应用程序设置的实在的请求头的列表。(同样,那并不包蕴浏览器设置的伏乞头。)
此处有2个响应报文例子,若是服务器允许请求:

皇冠官方网站 8

image.png

一呼百应包蕴2个Access-Control-Allow-Methods列出允许的不二法门、和可选三个Access-Control-Allow-Headers头列表允许的头。假若preflight请求成功,浏览器发送实际的请求,如前所述。

创建WebService 项目

皇冠官方网站 9

image.png

累加二个 名为 TestControllerWeb API 控制器

using System.Net.Http;
using System.Web.Http;

namespace WebService.Controllers
{
    public class TestController : ApiController
    {
        public HttpResponseMessage Get()
        {
            return new HttpResponseMessage()
            {
                Content = new StringContent("GET: Test message")
            };
        }

        public HttpResponseMessage Post()
        {
            return new HttpResponseMessage()
            {
                Content = new StringContent("POST: Test message")
            };
        }

        public HttpResponseMessage Put()
        {
            return new HttpResponseMessage()
            {
                Content = new StringContent("PUT: Test message")
            };
        }
    }
}

您能够在地头运转应用程序或陈设到Azure。(本学科中的截图,作者Web应用程序计划到Azure应用服务。)验证web
API是或不是运维成功,导航到http://hostname/api/test/,主机名是署应用程序时接纳的域名。您应该看到响应报文,“GET:
Test Message”。

皇冠官方网站 10

image.png

[EnableCors]参数headers介绍

[EnableCors]特点的headers,内定了哪贰个HTTP请求头能够访问能源。为了使别的请求头都足以访问,使用通配符“
* ”,八个允许的headers之间利用几个逗号来分隔。

   [EnableCors(origins: "http://example.com", 
    headers: "accept,content-type,origin,x-my-header", methods: "*")]

介绍

本课程演示了ASP.NET Web API.中使用 COCR-VS。大家将率先创设八个ASP.NET
项目。1个含有Web
API控制器的“WebService”,其它3个别的“WebClient”,它调用Web瑟维斯的接口。因为五个应用程序在不相同的世界,1个AJAX请求从WebClient到WebService是3个跨源的渴求。

皇冠官方网站 11

跨域请求流程

在跨域请求中通过证书请求

跨域请求中运用证书需求新鲜处理。私下认可情状下,浏览器不发送任何证件凭证与跨源的须要。凭证不但包涵cookies还包涵HTTP身份验证方案。为了在跨源请求发送凭证,客户端必须安装XMLHttpRequest.withCredentials为true。

  • c#

var xhr = new XMLHttpRequest();
xhr.open('get', 'http://www.example.com/api/test');
xhr.withCredentials = true;
  • JS

$.ajax({
    type: 'get',
    url: 'http://www.example.com/api/test',
    xhrFields: {
        withCredentials: true
    }

其余,服务器必须同意凭据。在Web
API,(EnableCors)天性的允许跨源凭证SupportsCredentials参数设置为true

[EnableCors(origins: "http://myclient.azurewebsites.net", headers: "*", 
    methods: "*", SupportsCredentials = true)]

假定那脾性子是true,HTTP响应将包涵Access-Control-Allow-Credentials头。这几个头告诉浏览器跨源请求的服务器允许凭据。
万一浏览器发送证书,不过响应不包蕴八个管用的Access-Control-Allow-Credentials头,浏览器不会领悟响应应用程序,并且AJAX请求战败。
务必小心将SupportsCredentials设置为true,因为这象征在二个网站在另一个域方可发送一个签到的用户的凭据代表用户的Web
API,。CORubiconS还分明,设置“*”的Origin是无用的,在SupportsCredentials是true的事态下。

安装允许响应标头

默许情状下,浏览器不领聚会场全数的应用程序响应标头。可用的响应头默许情状下是:

Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma

CO奥迪Q5S
规定了调用那一个回顾的响应头。于应用程序中利用其它头文件,请设置[EnableCors]的exposedHeaders参数
在接下去的例证中,控制器的Get方法设置一个自定义标头命名为“X-Custom-Header”。默许情状下,浏览器不会在跨源的呼吁中暴露无遗那一个自定义标头。为了使自定义标头有效,使
exposedHeaders 参数的值为X-Custom-Header”。

[EnableCors(origins: "*", headers: "*", methods: "*", exposedHeaders: "X-Custom-Header")]
public class TestController : ApiController
{
    public HttpResponseMessage Get()
    {
        var resp = new HttpResponseMessage()
        {
            Content = new StringContent("GET: Test message")
        };
        resp.Headers.Add("X-Custom-Header", "hello");
        return resp;
    }
}

相关文章