跨域CORS的问题

是什么

Cross-origin Resource Sharing 中文名称 “跨域资源共享” 简称 “CORS”,它突破了一个请求在浏览器发出只能在同源的情况下向服务器获取数据的限制。

浏览器的限制

浏览器限制了从脚本内发起的跨源 HTTP 请求。当一个请求在浏览器端发送出去后,服务端是会收到的并且也会处理和响应,只不过浏览器在解析这个请求的响应之后,发现不属于浏览器的同源策略(地址里面的协议、域名和端口号均相同)也没有包含正确的 CORS 响应头,返回结果被浏览器给拦截了。

预检请求

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

CORS 将请求分为了两类:简单请求和非简单请求。

预检请求定义

根据 MDN 的文档定义,请求方法为:GET、POST、HEAD,请求头 Content-Type 为:text/plain、multipart/form-data、application/x-www-form-urlencoded 的就属于 “简单请求” 不会触发 CORS 预检请求。

例如,如果请求头的 Content-Type 为 application/json 就会触发 CORS 预检请求,这里也会称为 “非简单请求”。

服务端设置

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 表示该响应的有效期,单位为秒。在有效时间内,浏览器无须为同一请求再次发起预检请求。还有一点需要注意,该值要小于浏览器自身维护的最大有效时间,否则是无效的。

其他

除了在应用(flask、django等)里面设置外。

Nginx 代理服务器配置跨域
使用 Nginx 代理服务器之后,请求不会直接到达我们的 Node.js 服务器端,请求会先经过 Nginx 在设置一些跨域等信息之后再由 Nginx 转发到我们的 Node.js 服务端,所以这个时候我们的 Nginx 服务器去监听的 3011 端口,我们把 Node.js 服务的端口修改为 30011,简单配置如下所示:

server {
  listen          3011;
  server_name     localhost;

  location / {
    if ($request_method = 'OPTIONS') {
      add_header 'Access-Control-Allow-Origin' 'http://127.0.0.1:3010';
      add_header 'Access-Control-Allow-Methods' 'PUT,DELETE';
      add_header 'Access-Control-Allow-Headers' 'Test-CORS, Content-Type';
      add_header 'Access-Control-Max-Age' 1728000;
      add_header 'Access-Control-Allow-Credentials' 'true';
      add_header 'Content-Length' 0;
      return 204;
    }

    add_header 'Access-Control-Allow-Origin' 'http://127.0.0.1:3010';
    add_header 'Access-Control-Allow-Credentials' 'true';

    proxy_pass http://127.0.0.1:30011;
    proxy_set_header Host $host;
  }
}

参考文章: https://github.com/qufei1993/http-protocol/blob/master/docs/cors.md


右下角对话与我联系。


评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×