博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Nginx解决CORS跨域解决方案
阅读量:5824 次
发布时间:2019-06-18

本文共 3287 字,大约阅读时间需要 10 分钟。

hot3.png

首先通读下 MDN 关于 CORS 的 ,了解跨域的含义及简单请求和复杂请求等的定义。文中的内容不赘述,现在说解决方案。

通过定义我们可以,简单请求与复杂请求的差别是复杂请求会自动发出一个 OPTIONS 的预检请求,当请求得到确认后,才开始真正发送请求。

综上,我们要解决两个问题:

  1. OPTIONS 请求的正确响应
  2. 跨域请求正确响应

Q1: OPTIONS 请求的正确响应

解决的方式有多种,既可以在Web Server解决,也可以在源码层解决。因为问题比较普遍,故我们选择在Web Server解决,下面我们以 Nginx 为例,说明解决方案。

假设访问的地址为 /example , Nginx 配置如下:

location /example {    proxy_redirect off;    proxy_set_header Host $host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_pass http://127.0.0.1:8080/;  }

为了解决跨域问题,添加如下内容:

location /example {+   if ($request_method = 'OPTIONS') {+       add_header Access-Control-Allow-Origin *;+       add_header Access-Control-Max-Age 1728000;+       add_header Access-Control-Allow-Methods GET,POST,OPTIONS;+       add_header Access-Control-Allow-Headers  'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';+       add_header Content-Type' 'text/plain; charset=utf-8';+       add_header Content-Length 0 ;+       return 204;+    }    proxy_redirect off;    proxy_set_header Host $host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_pass http://127.0.0.1:8080/;   }

解释:

if ($request_method = 'OPTIONS') {...} 当请求方法为 OPTIONS 时:

  1. 添加允许源 Access-Control-Allow-Origin 为 * (可根据业务需要更改)
  2. 添加缓存时长 Access-Control-Max-Age,当下次请求时,无需再发送 OPTIONS 请求
  3. 添加允许的方法,允许的首部
  4. 添加一个内容长度为0,类型为 text/plain; charset=utf-8 , 返回状态码为 204 的首部

至此,完成 OPTIONS 请求的正确响应。

Q2: 跨域请求正确响应

添加如下内容:

location /example {   if ($request_method = 'OPTIONS') {       add_header Access-Control-Allow-Origin *;       add_header Access-Control-Max-Age 1728000;       add_header Access-Control-Allow-Methods GET,POST,OPTIONS;       add_header Access-Control-Allow-Headers  'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';       add_header Content-Type' 'text/plain; charset=utf-8';       add_header Content-Length 0 ;       return 204;    }+   if ($http_origin ~* (https?://(.+\.)?(example\.com$))) {+     add_header  Access-Control-Allow-Origin $http_origin;+     add_header  Access-Control-Allow-Credentials true;+     add_header  Access-Control-Allow-Methods GET,POST,OPTIONS;+     add_header  Access-Control-Expose-Headers Content-Length,Content-Range;+   }    proxy_redirect off;    proxy_set_header Host $host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_pass http://127.0.0.1:8080/;   }

解释:

if ($http_origin ~* (https?://(.+\.)?(example\.com$))) {...}, 当 origin 为合法域名(可根据业务调整或去除合法域名验证)时:

  1. 添加允许源Access-Control-Allow-Origin为 $http_origin (可根据业务需要更改)
  2. 添加允许认证Access-Control-Allow-Credentials为 true ,允许接收客户端 Cookie(可根据业务需要更改。 但要注意,当设置为true时,Access-Control-Allow-Origin 不允许设置为 *)
  3. 添加允许的方法,暴露的首部

至此,完成跨域请求正确响应。

以上,是对跨域请求在Web Server的解决方案,主要是通过响应 OPTIONS 方法和添加允许源来解决。

当然,如果本地开发中,可以在利用 webpack-dev-server 的  选项来快速解决跨域问题:

示例如下:

// webpack.congf.jsmodule.exports = {  //...  devServer: {    proxy: {      '/api': {        target: 'http://localhost:3000',        pathRewrite: {'^/api' : ''}      }    }  }}

当访问地址如 /api/foo?q=bar 时,则通过代理访问的实际地址是: http://localhost:3000/foo?q=bar

CORS跨域请求并不魔幻,理解 CORS 的含义,根据规则去找方法就迎刃而解了。希望能帮助到大家。

以上。

转载于:https://my.oschina.net/liuyuantao/blog/1931256

你可能感兴趣的文章
OpenCV初探
查看>>
jmf找不到摄像头设备解决办法
查看>>
[Delphi] Delphi版本号对照
查看>>
[随感]GIS开发的困惑
查看>>
PHP的数组排序函数
查看>>
React中的代码分割
查看>>
转自把《编程珠玑》读薄
查看>>
html基础
查看>>
DNS服务解析检测脚本:
查看>>
魔法方法 __slots__ 方法
查看>>
BZOJ 3436 小K的农场 差分约束
查看>>
zend studio(Eclipse)和PyDev搭建Python开发环境
查看>>
dubbo框架原理
查看>>
《暗时间》
查看>>
微信 单页面 分享功能 问题 记录
查看>>
OpenWRT开发之——对C++的支持(解决库依赖问题)【转】
查看>>
RESTful 个人理解总结【转】
查看>>
Android 动态改变图片的颜色值
查看>>
RabbitMQ指南之一:"Hello World!"
查看>>
mybatis plus 代码生成器
查看>>