跨域请求产生错误的原因及处理方法
如果你在开发网站时曾经尝试通过框架或是浏览器的 fetch、XHR 请求过外部 API 的话,那么一定遇到过跨域请求,还有那个触目惊心的 CORS 错误信息;今天咱们来讨论跨域问题的原因以及解决方法。

跨域请求
如果你没有没有遇过,可以试着在浏览器的 console 页输入下面的代码:
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
console.log(xhr.status === 200 ? xhr.responseText : 'error')
}
}
xhr.open('GET', 'https://google.com')
xhr.send()
这段代码通过调用浏览器的 XMLHttpRequest 对 Google 发出请求,而得到的结果如图所示:
这就是跨域请求问题,当通过 JavaScript 对不同的来源发送请求时,这个请求的响应就会被浏览器拦截,不交给 JavaScript 处理。这里的“不同来源”指的是目标资源与当前网页的域(domain)、通讯协议(protocol)或网络端口(port)只要有任一项不同,就算是不同来源。例如下面这几个例子:
假设当前用户在:https://example.com :
[✅] https://example.com/test -> 同域
[❌] https://m.example.com -> 不同域
[❌] https://example.com:3000 -> 端口不同
[❌] -> 通讯协议不同
理解什么是跨域了,那为什么浏览器要把跨域请求资源拦截掉呢?
其实这是考虑到用户的信息安全。
假设小黑是一个恶意开发者,他编写的网站会尝试通过 XHR 打向百度、微博等目标网站;如果使用者原先就有目标网站的登录状态,小黑便能窥探他的隐私,得到不该取得的数据。再想想看,如果目标网站换成 Email、银行、电商,如果没有浏览器限制跨域请求的保护,恶意开发者便能为所欲为。
注意:跨域请求虽然会被浏览器拦截下来,但拦截的是响应(Response)而不是请求(Request)。
解决方案
关于跨域请求的解决方案有很多,例如 JSONP,也就是通过 HTML 中没有跨域限制的标签如 img、script 等,再通过指定回调函数,将响应的内容介接回 JavaScript 中;或是通过 iframe,绕过跨域保护获取目标资源等。下面仅说明两种常见也相对正规的解决方式。
1. CORS
最标准、正确的解决方法是通过 W3C 规范 的“ 跨域资源共享(Cross-Origin Resource Sharing ,CORS)”,通过服务器在 HTTP 头中的设置,可以使浏览器能够获取不同来源的资源。
CORS 规范中,清楚定义了跨域存取控制的运作方式。
首先服务器端需要在响应头中加上如 Access-Control-Allow-Origin、Access-Control-Request-Method、Access-Control-Request-Headers 等设定,来限制服务器所能接受的来源、请求的方法、可携带的头等等。
当浏览器发送资源请求时,如果是简单请求便会直接送出请求;若不符合前述条件,则会通过预检(Preflighted)请求先敲敲门,确认是否可以通过服务器的限制,然后才会发送正式的请求。
CORS 除了上述內容外,也有关于 Cookies 的传送方式,如何允许跨域写入 Cookies 等内容。
2. 代理服务器
由于 CORS 的头设置是在服务器端,如果服务器是自己的,那么可以轻易的调整服务器设置,让前端能取得必要的资源;但如果你请求的是外部 API,总不能每次遇到 CORS 错误,就要求别人去修改头设置吧。
简单暴力的方法就是通过代理服务器帮我们获取资源;由于跨域保护的限制是浏览器的规范,只要不通过浏览器发送请求,自然也就不会有限制。
常见的作法是通过 nginx 做简单的反向代理;例如在自己的开发环境,前后端分离的架构,前后端服务分别启动在 3000 和 5000 端口,则可以用这样的配置:
server{
listen 3000;
server_name localhost;
location ^~ /api {
proxy_pass :5000;
}
}
当前端需要发送 API 请求时,可以直接请求 localhost:3000/api/...,这个请求会被 nginx 拦截,并转发给后端所在的 localhost:5000,这样就能简单的绕过跨域保护了。
总结
跨域是前端常见的需求,CORS 的错误信息也是我们很容易被卡住的地方;其实只要清楚 CORS 规范中的 HTTP 头设置,并在服务器端做对应的调整,就可以顺利的完成跨域请求。
原文地址:https://mp.weixin.qq.com/s?__biz=MzI3NzIzMDY0NA==&mid=2247495014&idx=1&sn=080486c3d1728c22daad38f3f707d04a&chksm=eb6bc83ddc1c412bdca291568035478cae2d6cd01ba9e0f0f64e8f8f199511aed8c570550994&mpshare=1&s
相关热词: 方法
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://www.juheyunku.com/jiaob/bcjs/8319.shtml
相关文章
热门TAG
命令 外链 企业网站 白帽 php 织梦教程 dedecms修改内容 javascript 织梦 功能 标签 调用 详解 技巧 权重 服务器 网站流量 Dedecms 织梦cms HTML tags标签 python jquery教程 jquery windows 蜘蛛 搜索引擎 网站收录 JSP 实例解析最新文章
-
大牛眼中的好代码是什么
时间:2021-01-05
-
大数据专业毕业生未来可
时间:2021-01-05
-
看看人家那后端API接口写
时间:2021-01-05
-
详解三大编译器:gcc、l
时间:2021-01-05
-
超级干货:什么是低代码
时间:2021-01-05
-
如何在整个DevOps中建立分
时间:2021-01-05
-
如何从零思考设计你的
时间:2021-01-05
-
Vue源码中值得学习的方法
时间:2021-01-05
热门文章
-
20个有争议的编程观点
时间:2020-12-25
-
从0学ARM-汇编伪指令、LDS详解
时间:2020-12-26
-
你需要了解的几种微前端解决方案
时间:2020-12-27
-
2020年编程语言排行榜单年终大盘点
时间:2020-12-23
-
高级语言中的语句在汇编中是如何实现的
时间:2020-12-27
-
8 个让我更有效率的 Git 别名
时间:2020-12-27
-
一个高薪的码农,应具备的8种能力
时间:2020-12-25
-
Vue源码中值得学习的方法
时间:2021-01-05
-
大数据clouderaManager5.14.0离线部署
时间:2020-12-26
-
如何互联网没了女性的编程会怎样?
时间:2020-12-27
