【JavaScript】跨域解决方案
2021/09/09 14:54:16
关于跨域
跨域问题只会出现在浏览器环境中,因为浏览器用同源策略来保证客户端的安全。
单纯靠前端是无法实现跨域的
跨域问题的关键在于,在哪些域能跨域访问你服务器这件事上,只有服务器端才是权威的。所以任何跨域的解决方案,都必须要向服务器拿授权列表。
技术跨域
- 服务器由自己控制:CORS
- 服务器不由自己控制:代理服务
浏览器跨域
解决不了问题就解决提出问题的人。。。
- 关闭浏览器的安全检测,chrome:-disable-web-security
- 浏览器插件
跨域方法
jsonp
前后端约定统一的回调函数名称,前端在页面中定义该函数,函数的参数就是接口返回数据,后端则需要在接收该请求后将数据传递给该函数,并将整个函数返回
原理
<script>
标签的src
属性不受同源策略限制,可以访问不同域的资源,把这个标签插入页面后,标签内的js
代码会被执行- 在需要跨域请求的页面定义好回调函数,参数作为接口返回值去进行处理
- 前端动态创建
<script>
标签请求接口
缺陷
只能发送 get 请求
CORS
服务端允许跨域
nginx
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Credentials' true;
#
# 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-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-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';
}
}
ExpressJS
app.all("*", function (req, res, next) {
// 设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin", "*");
// 允许的header类型
res.header("Access-Control-Allow-Headers", "content-type");
// 跨域允许的请求方式
res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
if (req.method.toLowerCase() == "options")
res.send(200); // 让options 尝试请求快速结束
else next();
});
服务器代理
通过服务端代理到相同的域名下
跨域下载资源
浏览器中经常有下载资源(图片、文件)的需求,对于同源的资源很好解决,但是如果资源在其他服务器、域名下,就会有跨域问题,导致资源无法下载。
- 后端下载资源
可以在后台将需要下载的资源请求回来(后台请求没有跨域问题),处理后返回前端实现跨域资源下载。