Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结

HTTP响应头和请求头信息对照表
浏览器 AJAX 跨域请求访问控制
HTTP Method 详细解读(GET HEAD POST OPTIONS PUT DELETE TRACE CONNECT)

从MVC到前后端分离,必然要处理CORS(Cross-Origin Resource Sharing)/同源策略(same-origin policy)的问题。Cross-Origin:跨域(源)。same-origin:同源(域)。

如果不同源:
Cookie、LocalStorage 和 IndexDB 无法读取。
DOM 无法获得。
AJAX 请求不能发送。:同源政策规定,AJAX请求只能发给同源的网址,否则就报错。可使用 JSONP、WebSocket、CORS规避。
浏览器同源政策及其规避方法详细参考 此链接。

跨域资源共享 CORS 详解

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器:Web端发送跨域请求(简单请求/非简单请求),服务器预处理请求,允许请求则处理,否则不处理。

AJAX 请求CORS规避方法:
CORS请求分成两类:1,简单请求。2。非简单请求

  1. 简单请求

    1.  请求方法是以下三种方法之一:
        HEAD、GET、POST
    2. HTTP的头信息不超出以下几种字段:
        Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain。
        这就意味着,如果请求中添加了自定义Header,就属于非简单请求,就需要Server端处理预检验(Option)请求。
    3.  简单请求基本流程
        web端:
    

    Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结_第1张图片
    浏览器自动携带Origin: http://localhost:4200
    Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结_第2张图片

    4.  Serer端要对请求做响应处理:允许哪些域(源)请求(Access-Control-Allow-Origin),是否允许 发送请求的域(源)发送Cookie(Access-Control-Allow-Credentials)【如果不允许,web端withCredentials即便设为True也将无法传递cookie】
    
    5.  以上,web端请求发送,server端允许发送,然后服务端才接受web端的请求与传递的cookie,并做进一步的出来。
    
  2. 非简单请求
    非简单请求发送请求时,从浏览器端来看是浏览器发送了2次请求,第1次是option方法的请求,是预检请求;第2次是实际的请求。
    简单请求从浏览器端来看是只发送1此实际的请求,内部处理上算是发送了一次半的请求,服务器响应后的半次请求不是从浏览器发出(纯属臆测)。

    1. 预检请求
      web端,请求中添加了个自定义header:X-CustomToken,请求发送时会先执行option方法的请求。
      Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结_第3张图片

      Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结_第4张图片
      预检请求在 MVC项目执行时,预检阶段不会执行Action,必须要在请求发出前做处理:

      server端:对应【从MVC到前后端分离】里的SecurityAspect 一段
      Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结_第5张图片
      Application_BeginRequest()执行完预检请求判断,并做处理(响应预检请求:Access-Control-Allow-Methods、Access-Control-Allow-Headers、Access-Control-Allow-Credentials等),请求会再次进入Application_BeginRequest(),进行第二次实际方法的请求,请求方法不再是Option,之后才会去执行Action。
      Web端第1次预检请求(Option)
      Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结_第6张图片

    2. 实际请求
      Web端第2次实际请求(POST)
      Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结_第7张图片
    3. 获取Response的自定义header
      如果是跨域请求(CORS), 自定义的Header会从server端的response headers 带回浏览器,但始终将无法通过代码response.headers.get(“X-TOKEN”)取得, Server-side必须要添加 “Access-Control-Expose-Headers” 到Response中才行。
      这里写图片描述

      这里写图片描述

      Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结_第8张图片

被 跨域自定义Header请求 问题困扰了这么久总是解决了,最后能解决要感谢博客园里这位大兄弟 链接:跨域请求web api,如果headers传递数据,请求无响应。
关键点:Application_BeginRequest()方法
ASP.NET Requst请求事件处理顺序:
Angular 笔记 三、 跨域请求、自定义Header、预检验(option)总结_第9张图片

之后可能还会遇到“IIS中WebDav和OPTIONSVerbHandler会对OPTIONS请求有特殊处理,会截断后面的请求”的问题

<remove name="WebDav" />
<remove name="OPTIONSVerbHandler" />

“这两个到webconfig里终于在iis里正常了”。

另附OPTIONSVerbHandler相关链接,以后备查:
关于跨域的二三事

asp.net web api 中的坑。 web.config 中 remove name=”OPTIONSVerbHandler” 需要去掉。

Angular访问WebApi出现options方法

你可能感兴趣的:(c#-web,angular,CORS)