跨域(CORS)产生原因分析与解决方案。
产生跨域的原因?

当一个请求在浏览器发出的时候,服务器会接受并且也会处理和响应。只不过浏览器在解析这个请求响应之后,发现不属于浏览器的同源策略(地址里面的协议,域名,端口都不相同),也没有包含正确的cors响应头,返回的结果就会被拦截。

预检请求

预检请求是在发送实际请求之前,客户端会先发送一个options方法的请求向服务器确认,如果通过之后就会发送真正的请求,这样可以避免跨域对服务器的用户数据造成的影响。

预检请求定义

CORS分为简单请求和非简单请求。简单请求即为:请求方法为get、post、head,请求头为text/plain、multipart/form-data、application/x-www-form-urlencoded属于简单请求,不会触发CORS预检请求。 非简单请求例如为:Content-Type:application/json就会触发CORS请求。 非简单请求Request Headers:

OPTIONS /api/data HTTP/1.1 Host: 127.0.0.1:3011 Access-Control-Request-Method: PUT Access-Control-Request-Headers: content-type,test-cors Origin: http://127.0.0.1:3010 Sec-Fetch-Mode: cors

可以看出options是预检请求使用的方法,该方法是在http/协议中所定义,还有一个重要的字段origin请求表示请求来自哪个源。服务器可以根据这个字段来判断是否是合法的请求源。 Access-Control-Request-Method:告诉服务器请求的方法。 Access-Control-Request-Headers:告诉服务器,实际请求头部字段

设置服务器

res.writeHead(200, { 'Access-Control-Allow-Origin': 'http://127.0.0.1:3010', 'Access-Control-Allow-Headers': 'Test-CORS, Content-Type', 'Access-Control-Allow-Methods': 'PUT,DELETE', 'Access-Control-Max-Age': 86400 });

解释一下: Access-Control-Allow-Origin:表示‘http://127.0.0.1:3010’这个请求源是可以使用的,该字段设置为‘*’表示允许任意跨域源请求。 Access-Control-Allow-Methods:表示服务器允许客户端使用 PUT、DELETE 方法发起请求,可以一次设置多个,表示服务器所支持的所有跨域方法,而不单是当前请求那个方法,这样好处是为了避免多次预检请求。 Access-Control-Allow-Headers:表示服务器允许请求中携带 Test-CORS、Content-Type 字段,也可以设置多个。 Access-Control-Max-Age 表示该响应的有效期,单位为秒。在有效时间内,浏览器无须为同一请求再次发起预检请求。还有一点需要注意,该值要小于浏览器自身维护的最大有效时间,否则是无效的。

如何解决跨域

1.后端配置方案

router.all('/getCityList', function(req,res,next){
//*表示支持所有网站访问,也可以额外配置相应网站
    res.header('Access-Control-Allow-Origin','*')
    next()

2.JSONP 方式

$.ajax({
    type:"get",
    async:false,
             url:"http://localhost:8080/JavaWeb01/getPassWordByUserNameServlet?userName=Tom",
    dataType:"jsonp",//数据类型为jsonp
    jsonp:"backFunction",//服务端用于接收callBack调用的function名的参数
    success:function (data) {
    lert(data["passWord"]);
         },
    error:function () {
          alert("error");
     }

  });

3.nginx 代理

跨域(CORS)产生原因分析与解决方案_Access