1
magicZ 135 天前
前端网站地址: http://localhost:8080
服务端网址: http://localhost:59200 # nginx 跨域配置 server { listen 22222; server_name localhost; location / { add_header Access-Control-Allow-Origin 'http://localhost:8080' always; add_header Access-Control-Allow-Headers '*'; add_header Access-Control-Allow-Methods '*'; add_header Access-Control-Allow-Credentials 'true'; if ($request_method = 'OPTIONS') { return 204; } proxy_pass http://localhost:59200; } } 来源 https://mp.weixin.qq.com/s/VzWlJ8laLn8AI-JoiDepug |
2
kxg3030 135 天前
比较合理 除了头部那里
|
3
chenliangngng 135 天前
没啥问题,但是只限定自家公司产品,有的配置是专有的
|
5
salmon5 135 天前
合理个锤子,add_header 指令不能放在 if 里,要用 map 。
|
6
coolcoffee 135 天前 1
如果不是非必要,最好从后端 web server 框架里面加 CORS ,不然很容易出现双 CORS 响应头反而导致失效。
|
7
salmon5 135 天前
@coolcoffee #6 这样是最规范和合理的,谁的问题谁解决。小作坊公司一般是加到 nginx ,省事。
|
8
ilvsxk 135 天前 1
@magicZ #1
在响应附带身份凭证的请求时(通常是 Cookie ): 服务器不能将 Access-Control-Allow-Headers 的值设为通配符“*”,而应将其设置为标头名称的列表,如:Access-Control-Allow-Headers: X-PINGOTHER, Content-Type 服务器不能将 Access-Control-Allow-Methods 的值设为通配符“*”,而应将其设置为特定请求方法名称的列表,如:Access-Control-Allow-Methods: POST, GET |
9
vueli 135 天前
就我所知,最好的跨域解决方案就是前端 nginx 开一个反向代理
|
10
mjollnirray 135 天前
if is evil
|
11
mjollnirray 135 天前 1
server {
listen 22222; server_name localhost; location / { add_header Access-Control-Allow-Origin 'http://localhost:8080' always; add_header Access-Control-Allow-Headers '*'; add_header Access-Control-Allow-Methods '*'; add_header Access-Control-Allow-Credentials 'true'; if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin 'http://localhost:8080' always; add_header Access-Control-Allow-Headers '*'; add_header Access-Control-Allow-Methods '*'; add_header Access-Control-Allow-Credentials 'true'; return 204; } proxy_pass http://localhost:59200; } } |
12
concernedz 135 天前 2
# 跨域 START
if ($http_origin !~* "^( http://localhost:1617|http://localhost:8080)$") { return 403; } add_header Access-Control-Allow-Origin $http_origin always; add_header Access-Control-Allow-Methods 'GET,POST,PATCH,PUT,DELETE,OPTIONS'; add_header Access-Control-Allow-Headers 'Authori-zation,Authorization,Content-Type,If-Match,If-Modified-Since,If-None-Match,If-Unmodified-Since,X-Requested-With,Form-type,Cb-lang,Invalid-zation'; add_header Access-Control-Allow-Credentials 'true'; add_header Access-Control-Max-Age '1728000'; if ($request_method = 'OPTIONS') { return 204; } # 跨域 END v2 不支持 md 写法吗 |
13
cat 135 天前 1
@concernedz 评论不支持 markdown
|
14
ragnaroks 135 天前
以我个人了解,只要 Access-Control-Allow-Origin 的值不是 * 就已经合格了
|
15
ETiV 135 天前 1
看你想干啥……本地开发随便写写,线上这么写有问题。。。
★ Allow-Origin 赋值成 $http_origin ,就等价于 allow * origin 是请求时携带的网页 URL ,现在这么配,是来者不拒的意思,或者像 #12 那样提前判断下。 ★ 应该仅在必要的 Method & URL 上加 header 字段,而不是直接写在 server {…} 或 location / {…} 这样粗暴。 我们为了减少静态资源的 overhead 流量会给 CDN 单独买个域名,就是为了在请求和响应期间减少 header 所携带的内容。CORS 这种功能性的 header 应该仅在必要时出现。 ★ 后端框架也需要注意的一点 我遇到过一个网站,虽然有 CORS 策略阻止我干坏事儿,但是他们 jsonp 是开着的。我觉得是后端框架的锅,默认开启了 jsonp 的特性,URL 追加个 ?callback=jsonp_xxxx 还是能从前端跨域拿到对方的数据… |
16
yuanxiaosong 134 天前
@coolcoffee 正常正好相反,一个后端 API 可能对应 n 个业务线,每个业务线又有 n 个产品,鬼才知道前端用的什么域名,所以我们的操作是使用 proxy_hide_header ,不管后端服务设置什么跨域全部丢弃掉。
|
17
yuanxiaosong 134 天前
@salmon5 我倒是觉得小公司才在后端服务里面写跨域,一般来说环境有开发/测试/预发布/生产(蓝/绿)/演示环境等,并且一个公共服务 API 会被多个产品调用,每个产品一级域名都不一样,有些产品客户还有私有化部署需求,还没考虑私有化部署需求,难道让后端把所有域名都收集好写到代码/配置里面,每次新增一个域名都改一次后端服务?众所周知,Access-Control-Allow-Origin 只能是单个域名或者*,如果一个 api 对应多个不同一级域名,代码还要
if (ALLOW_ORIGINS.contains(requestDomain)) { resp.addHeader("Access-Control-Allow-Origin", requestDomain); } 这种写法,不难受么? |
18
salmon5 134 天前
@yuanxiaosong #抽出来,可配置的,跨域是业务问题,业务来解决。
否则就会前端、后端、运维 3 方扯皮。本来就是后端自己的事情。 |
19
salmon5 134 天前
@yuanxiaosong 规模大了,业务网关上配置也行。
|
20
coolcoffee 134 天前
@yuanxiaosong 虽然现在 cookie 不是很常见了,但是如果需要能支持 cookie 那还是需要单个域名,那这个只有交给业务框架的 web server 来处理才行。
我的做法是一个公司的对外顶级域名毕竟还是可枚举,我知道的大部分框架都是可以支持回调方法来返回一个 true or false 来放行,那么回调里面就可以改成匹配顶级域名的形式来放行。 |
21
ysc3839 134 天前 via Android 1
@salmon5 add_header 可以写 if 里,但是 if 要在 location 里。
https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header |