网易首页 > 网易号 > 正文 申请入驻

又是跨域,这次搞定它!

0
分享至

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

世界上没有没碰到跨域的程序员。

在平常工作中,我们不止一次听到过跨域这个词,尤其是和前端打交道的时候;当然安全部门有时候也会刷存在感,推给你XSS这样看起来高大上的名词;再就是从http协议升级成https协议的时候,也会碰到。

在后端开发中,并没有跨域这么麻烦的东西。因为只要网络连的通,我们就能够构造请求。所谓的跨域,是对于浏览器来说的,限制了各种条条框框,以便能够安全的驯服javaScript这只野兽。

换句话说,脱离了主流的浏览器,并没有跨域这么一说。就像是楚河汉界,脱离了棋盘,就是个谈资而已。

所以来吧,看看浏览器为了达到自己的目的,都干了些啥。

1. 跨域和同源

所谓的同源,指的是两个URL的协议(protocal)、域名(host)、端口(port)都相同的情况,可以说是非常严格了。下面给出一个示例。

对于http://xjjdog.cn/index.html来说,下面展示了4种不同的情况。

【1】https://xjjdog.cn/index.html 因为协议不同,一个是http一个是https,所以它们是不同源的。

【2】https://xjjdog.cn:8080/index.html 因为端口不同,一个是80,一个是8080,所以它们是不同源的。

【3】http://mall.xjjdog.cn/index.html 因为主机不同,所以依然是不同源的

【4】http://xjjdog.cn/index.htm 这种情况,因为只有目录是不同的,所以是同源的。

那么在不同源(跨域)的情况下,js的执行都有哪些限制呢?


  1. 首先是存储资源不共享。比如CookieLocalStorageIndexDB(浏览器数据库)等,都不能相互读取。



  2. 其次是跨域的情况下,DOM和Javascript对象都无法获取。



  3. 更要命的是,Ajax请求无法发送,限制了前端程序员的发挥。


但随着业务的增长和域名的增加,跨域的需求是越来越多,浏览器的默认行为,成为了这个功能的拦路虎。所以我们需要寻找有效的方法,来突破这条加载自己脖子上的锁套。

2. CORS 跨域资源共享

前端工程师很聪明,发明了各种各样的请求方法。常见的有:

  1. jsonp使用javascript的代理模式,动态的创建script标签。比如常见的百度统计代码,虽然不同源,但是你仍然能把信息发送过去。jsonp只能支持GET请求,不支持POST请求。

  2. document.domain + iframe这个是利用iframe加载主域名相同的资源。

  3. location.hash + iframe依然是利用iframe等,使用的是全局对象,用起来很绕。

  4. postMessageHtml5的新功能,专门用来解决跨域。我们只要发送端拥有某个窗口的有效js的句柄,就可以通过这套机制向该窗口发送任意长度的文本信息。但编程的时候,容易忘掉origin的判断,造成安全问题。

这些方法都需要写很多代码,还容易出错,调试起来也麻烦,所以现在用的最多的,是CORS。

这项技术是W3C的标准,前端代码几乎不需要做任何改动,浏览器可以自动完成。听起来非常的魔幻,但它其实是在HTTP协议上做文章的,要在Http的头里面,加入一些附加信息。只要服务器支持,就实现了跨域操作。所以通信的关键就有前端转移到了服务器的配置上。目前,几乎所有的浏览器都支持。

拿Nginx来说,要解决跨域,就得加一些配置。

location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' true;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# Custom headers and headers various browsers *should* be OK with but aren't
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
# Tell client that this pre-flight info is valid for 20 days
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' true;
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 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' true;
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 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

因为跨域,针对于正常的浏览器限制来说,相当于开了一条特许通道,所以它的配置非常的细腻。其中最重要的,就是Access-Control-Allow-Origin,我们一般设置成*一了百了,但它可以指定具体的请求来源,也更加安全。所以,在dev环境调试时,为了方便开发,可以设置成*,而线上最好设置成具体的domain。

Access-Control-Request-Method指定了跨域请求所允许的HTTP方法,我们这里是GET、POST、OPTIONS等。

Access-Control-Allow-Headers,表明服务器支持的所有头信息字段,用在预检请求中。值得注意的是,一些简单的头部信息,比如Content-Language、Content-Type等,不需要特别声明。如果你想偷懒,当然也有更好的方法。

Access-Control-Allow-Headers: *

那么,http的交互,是如何执行的呢?

我们假定浏览器访问的网址是http://xjjdog.cn,当浏览器访问的时候,它发起了一个指向http://xdddog.cn的Ajax请求。正常情况下,这是不能通过的。于是浏览器在请求头中,自动添加了一行。

Origin: http://xjjdog.cn

xdddog.cn的服务器(nginx)看到这个请求,一对比,可以啊兄弟,我允许你访问。

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials:true

那请求就可以正常进行下去,否则会触发XHRonerror

请求类型分为简单请求和复杂请求,细究起来一点意思都没有,建议访问https://www.test-cors.org/进行实际的测试来观测。

我们上面介绍的,其实就是简单请求的过程。

对于复杂请求来说,多了一步使用OPTIONS的预检操作,流程其实也差不多。

3. 其他地方怎么配置?

由于CORS应用非常广泛,所以现在所有的服务器端软件,都提供了对它的支持。对于tomcat来说,配置就简单的多,配置一个filter就可以了。


CorsFilterfilter-name>
org.apache.catalina.filters.CorsFilterfilter-class>
filter>
CorsFilterfilter-name>
/*url-pattern>
filter-mapping>

对于SpringBoot服务来说,就更加简单,直接通过注解就能完成。

@CrossOrigin(origins = "*",maxAge = 3600)

当然,它的属性也有很多。

  • origins 所有支持域的集合,也就是Access-Control-Allow-Origin

  • allowedHeaders 允许请求头重的header,不设置的话就是全部支持

  • exposedHeaders 响应头中允许访问的header

  • methods 请求支持的方法

  • allowCredentials 是否允许cookie随请求发送,使用时必须指定具体的域

  • default 预请求的结果的有效期,默认30分钟

所以,在SpringBoot下实现跨域,就是这么任性的简单。

4. End

跨域问题,在前后分离的架构下,几乎100%都会遇到。跨域访问的限制,是浏览器做的文章,我们可以使用CORS来绕过去。既然是绕,那就不要一股脑的全部设置成*,虽然这样搞非常的让人省心。

而有时候你确实会遇到连CORS都处理不了的跨域问题。在这种情况下,最好要求你的客户,升级一下支持的浏览器试试。毕竟有些特立独行的浏览器,是非常IE的。

作者简介:小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流。

1. 玩转Linux
2. 什么味道专辑

3. 蓝牙如梦
4. 杀机!
5. 架构师BUG,非比寻常

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
加拿大总理刚到北京,又有两国元首计划访华,特朗普突然喊话中国

加拿大总理刚到北京,又有两国元首计划访华,特朗普突然喊话中国

历史有些冷
2026-01-15 17:40:06
1955年,一名身体强壮的日本女人赤裸上身背着黑色编织袋站在海边

1955年,一名身体强壮的日本女人赤裸上身背着黑色编织袋站在海边

忠于法纪
2026-01-07 17:46:09
上海一服务员帮顾客拍照心生不满,发朋友圈辱骂“俩人才吃一千四,什么时候吃到一万四再让我服务你好吗?”

上海一服务员帮顾客拍照心生不满,发朋友圈辱骂“俩人才吃一千四,什么时候吃到一万四再让我服务你好吗?”

观威海
2026-01-16 14:46:02
南华寺百岁高僧:人死后基本都投身畜生道,活人进入轮回永不超生

南华寺百岁高僧:人死后基本都投身畜生道,活人进入轮回永不超生

纸鸢奇谭
2025-01-17 14:30:03
马未都:我身价至少100亿,但这点钱,跟我母亲比,我就是个贫农

马未都:我身价至少100亿,但这点钱,跟我母亲比,我就是个贫农

忠于法纪
2026-01-15 22:08:28
北京男篮6分完败 周琦5+9伤退;山西末节逆转 张宁14分是关键先生

北京男篮6分完败 周琦5+9伤退;山西末节逆转 张宁14分是关键先生

中国篮坛快讯
2026-01-16 21:52:21
执掌皇马23年!78岁佛爷或被迫离任:纵容熊皇胡闹 20年旧事重演

执掌皇马23年!78岁佛爷或被迫离任:纵容熊皇胡闹 20年旧事重演

风过乡
2026-01-16 07:43:33
抗美援朝时,美空军为何始终找不到彭老总的指挥所?有一关键人物

抗美援朝时,美空军为何始终找不到彭老总的指挥所?有一关键人物

大运河时空
2026-01-05 08:20:03
张军同志应邀到中央港澳办作讲座

张军同志应邀到中央港澳办作讲座

最高人民法院
2026-01-16 21:11:41
24小时内3位名人传离世噩耗,最大92岁,最小47岁,有人突遭意外

24小时内3位名人传离世噩耗,最大92岁,最小47岁,有人突遭意外

叨唠
2026-01-16 01:41:57
邓莎官宣离婚:白手起家不是豪门,结婚14年AA制,自己赚钱养父母

邓莎官宣离婚:白手起家不是豪门,结婚14年AA制,自己赚钱养父母

阿纂看事
2026-01-16 10:35:18
1969年,叶剑英被贬长沙,少将黎原机场怒斥秘书:这叫忘恩负义!

1969年,叶剑英被贬长沙,少将黎原机场怒斥秘书:这叫忘恩负义!

文史明鉴
2026-01-15 20:58:11
官宣,蒿慧杰任西安市委书记!

官宣,蒿慧杰任西安市委书记!

荣耀西安网
2026-01-16 19:38:06
女子回乡建厂5年:当初捧着邀请我来,如今被强拆4000万说没就没

女子回乡建厂5年:当初捧着邀请我来,如今被强拆4000万说没就没

今朝牛马
2026-01-16 18:14:40
震惊!你绝对想不到艾滋病高发地是这里!

震惊!你绝对想不到艾滋病高发地是这里!

特约前排观众
2026-01-15 00:10:08
太可怜了!云南4年级女孩穿着单衣瑟瑟发抖上学,老师出手暖人心

太可怜了!云南4年级女孩穿着单衣瑟瑟发抖上学,老师出手暖人心

火山诗话
2026-01-16 06:28:40
这球得跪着看!巴萨22岁中场大师40米直塞:撕裂4人防线 4场造7球

这球得跪着看!巴萨22岁中场大师40米直塞:撕裂4人防线 4场造7球

风过乡
2026-01-16 06:47:53
张学良之子回乡省亲,中央为何委托当地政府,付给张家2000万巨款

张学良之子回乡省亲,中央为何委托当地政府,付给张家2000万巨款

鹤羽说个事
2026-01-16 14:07:47
宁夏回族自治区人民政府原参事李明接受纪律审查和监察调查

宁夏回族自治区人民政府原参事李明接受纪律审查和监察调查

极目新闻
2026-01-16 15:20:29
不得了,这个新技术把视频压缩到了0.02%!

不得了,这个新技术把视频压缩到了0.02%!

量子位
2026-01-15 14:21:34
2026-01-16 22:24:49
小姐姐味道
小姐姐味道
十年架构,日百亿流量
329文章数 1203关注度
往期回顾 全部

科技要闻

传小米传音Ovi四家手机厂下调全年出货预期

头条要闻

温州一家企业火了:春节放假35天 准时返岗再发5000元

头条要闻

温州一家企业火了:春节放假35天 准时返岗再发5000元

体育要闻

全队身价=登贝莱,他们凭什么领跑法甲?

娱乐要闻

李湘翻车,早就有迹可循!

财经要闻

清流|酒店商家在携程和美团之间沦为炮灰

汽车要闻

方程豹品牌销量突破30万辆 2026年还将推出轿跑系列

态度原创

游戏
教育
艺术
旅游
手机

LCK春季赛:T1阵容初见峥嵘,三局战胜HLE,宙斯和姑妈有点难看

教育要闻

博主举报闫学品儿子林某

艺术要闻

300亿!341米!迪拜将建全球首个奔驰品牌城市

旅游要闻

文旅为桥 高平与青春共澎湃

手机要闻

iPhone 17e再次被确认:60Hz刷新率+A19芯片+灵动岛,上半年登场

无障碍浏览 进入关怀版