(Ext / Js) ajax 跨域请求发送两次解决方案

    我的项目都是前后端分离,在用ajax请求的时候总是会发送两次请求,一次OPTIONS(预检请求),一次正常的POST(OR GET)。通过浏览器的开发者调试工具(network)可以看到options请求不会带上任何参数,返回null(其实返回值可以在后台设置)。第二条请求才是我们想要的真正的请求。

    这个问题可以说并不是个问题,浏览器发现跨域时,会附加一次options请求。去判断是否是安全的请求,也就是CORS。整个过程由浏览器自动完成,用户不会感觉得到。但是对于开发者来说,总是不喜欢浪费资源。下面我会介绍如何去减少或者避免OPTIONS请求;

浏览器将CORS分为两中请求:简单请求(simple request)和复杂请求(not-so-simple-request),两种处理方式是不一样的。

一、简单请求:
简单请求头会被加上Origin字段,用于服务器判断是不是允许内的请求域名;
二、复杂请求:
在发送POST前,发送一条预检请求(OPTIONS),请求头也会带上Origin字段;

不管是简单请求还是复杂请求,我们都一视同仁;

先介绍一些CORS相关的字段:
1、Access-Control-Allow-Origin
这个字段是必须的,它的值代表着允许的域名。可以是请求头的Origin值,也可以是*。

2、Access-Control-Allow-Credentials
这个字段可选,代表着服务器是否允许这个域名请求携带Cookies,默认是不允许。需要请求带上Cookies,可以设置为true,也只能设置为true。否则就请删掉,不要傻乎乎的设置false。
想要拿到cookie,光服务器允许是不行的,客户端也要允许,在ajax中配置withCredentials:true。

3、Access-Control-Expose-Headers
可选。cors请求时XMLHttpRequest通过getResponseHeader()只能拿到ache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma这个6个基本的属性。想要拿到更多的可以再Access-Control-Expose-Headers中指定。

4、Access-Control-Request-Method
必填。这个字段代表的是服务器允许的请求方式。

5、Access-Control-Request-Headers
可选。指定浏览器CORS请求会额外发送的头信息字段,用逗号分隔。

6、Access-Control-Max-Age
可选。意思是有效期,单位是秒。在有效期内,不会发送另一条options请求。

一下是我在项目上的用法:(Ext6.2.0 + WebApi)
前端:
这里写图片描述

后台:
这里写图片描述

用Ext的同学可以继续往下看;

Ext的store请求数据时,以上的配置不会起作用,原因我也不清楚,但是可以配置代理的属性useDefaultXhrHeader: false;

store就不会用到跨域请求。

–完–


版权声明:本文为P_127原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。