借着首页在讨论跨域,一个运维朋友教我写的配置合适不?

166 天前
 YJi
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-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}

这么配置有没有啥问题?
2434 次点击
所在节点    程序员
21 条回复
magicZ
166 天前
前端网站地址: 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
kxg3030
166 天前
比较合理 除了头部那里
chenliangngng
166 天前
没啥问题,但是只限定自家公司产品,有的配置是专有的
guguji5
166 天前
salmon5
166 天前
合理个锤子,add_header 指令不能放在 if 里,要用 map 。
coolcoffee
166 天前
如果不是非必要,最好从后端 web server 框架里面加 CORS ,不然很容易出现双 CORS 响应头反而导致失效。
salmon5
166 天前
@coolcoffee #6 这样是最规范和合理的,谁的问题谁解决。小作坊公司一般是加到 nginx ,省事。
ilvsxk
166 天前
@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
vueli
166 天前
就我所知,最好的跨域解决方案就是前端 nginx 开一个反向代理
mjollnirray
166 天前
if is evil
mjollnirray
166 天前
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;
}
}
concernedz
166 天前
# 跨域 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 写法吗
cat
166 天前
@concernedz 评论不支持 markdown
ragnaroks
166 天前
以我个人了解,只要 Access-Control-Allow-Origin 的值不是 * 就已经合格了
ETiV
166 天前
看你想干啥……本地开发随便写写,线上这么写有问题。。。

★ 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 还是能从前端跨域拿到对方的数据…
yuanxiaosong
165 天前
@coolcoffee 正常正好相反,一个后端 API 可能对应 n 个业务线,每个业务线又有 n 个产品,鬼才知道前端用的什么域名,所以我们的操作是使用 proxy_hide_header ,不管后端服务设置什么跨域全部丢弃掉。
yuanxiaosong
165 天前
@salmon5 我倒是觉得小公司才在后端服务里面写跨域,一般来说环境有开发/测试/预发布/生产(蓝/绿)/演示环境等,并且一个公共服务 API 会被多个产品调用,每个产品一级域名都不一样,有些产品客户还有私有化部署需求,还没考虑私有化部署需求,难道让后端把所有域名都收集好写到代码/配置里面,每次新增一个域名都改一次后端服务?众所周知,Access-Control-Allow-Origin 只能是单个域名或者*,如果一个 api 对应多个不同一级域名,代码还要
if (ALLOW_ORIGINS.contains(requestDomain)) {
resp.addHeader("Access-Control-Allow-Origin", requestDomain);
}
这种写法,不难受么?
salmon5
165 天前
@yuanxiaosong #抽出来,可配置的,跨域是业务问题,业务来解决。
否则就会前端、后端、运维 3 方扯皮。本来就是后端自己的事情。
salmon5
165 天前
@yuanxiaosong 规模大了,业务网关上配置也行。
coolcoffee
165 天前
@yuanxiaosong 虽然现在 cookie 不是很常见了,但是如果需要能支持 cookie 那还是需要单个域名,那这个只有交给业务框架的 web server 来处理才行。

我的做法是一个公司的对外顶级域名毕竟还是可枚举,我知道的大部分框架都是可以支持回调方法来返回一个 true or false 来放行,那么回调里面就可以改成匹配顶级域名的形式来放行。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1056565

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX