一、跨域
- 跨域是由于浏览器的同源策略,当浏览器中一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。
- 同源策略(SOP)是一种约定,同源是指 协议、域名、端口号
三者相同,即便两个不用的域名指向同一个ip地址,也非同源。同源策略可以防止浏览器收到XSS、CSFR等攻击。 - 用户在使用浏览器的情况下会使用到 CORS,因为控制访问权限的是浏览器而非服务器。因此使用其它客户端的时候无需关心任何跨域问题。
二、如何解决跨域问题
1、代理配置
①webpack代理配置,Vue脚手架创建的项目在vue.config.js文件配置以下代理
devServer:{
proxy:{
'/api': {
// 需代理地址
target: 'https://example.com/',
host: '0.0.0.0',
port: port,
// https: true, // 允许https接口代理
// hotOnly: true, // 热更新
// 如果是代理到域名,需要设置changeOrigin: true
changeOrigin: true
// 路径重写(代理重写)
// 如果实际接口没有当前path则需重写路径,且使用调用接口的时候需要加上当前path
// 比如访问的API路径:/api/singIn,设置pathRewrite: {’^/api’ : ‘’},后,最终代理访问的路径:https://example.com/singIn
pathRewrite:{
'^/api':''
}
},
},
}
②nginx代理配置在nginx.conf文件内配置
location /api {
rewrite ^/api/?(.*)$ /$1 break;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 允许cros跨域访问
# add_header 'Access-Control-Allow-Origin' '*';
proxy_pass http://0.0.0.0:8080/; # 转发地址
}
2、JSONP
- 利用script标签 src属性,不存在跨域限制。发送 GET 请求 (无法实现POST请求)
- src = “http://127.0.0.1:4000/list?callback=func”
向服务器发送请求,同时会把本地的一个函数传递给服务器。 - JSONP需要服务器端支持。
- 核心思想:网页通过添加< script >标签,向服务器请求 JSON
数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。 - JSONP是解决跨域的方法之一,它与AJAX并无任何关联。
- JSONP向服务端发送的请求,type的类型为scrpt,这与JSONP的核心思想相对应。
- AJAX向服务端发送的请求,它的type类型为一个xhr对象,AJAX的源码就是先创建一个xhr的对象,然后发送请求,所以JSONP与AJAX没有任何关系,只是AJAX封装了JSONP。
①原生js使用JSONP
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function getData(data){
document.write(JSON.stringify(data))
}
</script>
<script src="http://localhost:3000/jsonp/jsonp?callback=getData"></script>
</body>
</html>
②jQuery 使用 JSONP
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP 实例</title>
<script src="https://cdn.static.runoob.com/libs/jquery/1.8.3/jquery.js"></script>
</head>
<body>
<div id="divCustomers"></div>
<script>
// 直接只用$.getJSON调用
$.getJSON("http://localhost:3000/jsonp/jsonp?callback=?", function (data) {
document.write(JSON.stringify(data))
});
// or
// 使用ajax,dataType设置为jsonp调用
$.ajax({
type : "GET",
dataType : "jsonp",
url : "http://localhost:3000/jsonp/jsonp",
success : function(data){
document.write(JSON.stringify(data))
console.log('data', data)
}
})
</script>
</body>
</html>
JSONP的缺点:1.不安全;2.只支持get 请求;3.需要服务器支持
3、CORS
CORS(Cross-Origin Resource Sharing,跨域资源共享),允许浏览器向跨域服务器,发出XMLHttpRequest请求,从而克服了AJAX只能使用限制。
XMLHttpRequest:Ajax的核心对象
CORS需要浏览器和服务器同时支持。
预检请求
跨域请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
如果服务器允许跨域,需要在返回的响应头中携带下面信息:
'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie
'Access-Control-Allow-Origin': '*', // 允许访问的域(协议+域名+端口)
'Access-Control-Allow-Methods': "POST,GET,DELETE,PUT,OPTIONS" // 允许请求方式用着五种`
'Access-Control-Allow-Headers':""允许携带的头
'Access-Control-Max-Age':""本次许可的有效时长,单位是秒,过期之前的ajax请求就无需再次进行预检了
缺点:要不让所有源都可以(所有源都不能携带cookie)要不然就只能允许一个源,可以携带cookie
参考:
1、https://blog.csdn.net/weiCong_Ling/article/details/130624934
2、https://blog.csdn.net/qq_46548855/article/details/129268826