什么是跨域问题就是前端调用的后端接口不属于同一个域(域名或端口不同),就会产生跨域问题,也就是说你的应用访问了该应用域名或端口之外的域名或端口。这都是同源策略在发挥作用。
同源策略
- 同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。
- 所谓同源是指”协议+域名+端口”三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
- 同源策略限制以下几种行为:
- Cookie、LocalStorage 和 IndexDB 无法读取
- DOM 和 Js对象无法获得
- AJAX 请求不能发送
下表给出了与 URL http://store.company.com/dir/page.html 的源进行对比的示例:
URL | 结果 | 原因 |
---|---|---|
http://store.company.com/dir2/other.html | 同源 | 只有路径不同 |
http://store.company.com/dir/inner/another.html | 同源 | 只有路径不同 |
https://store.company.com/secure.html | 失败 | 协议不同 |
http://store.company.com:81/dir/etc.html | 失败 | 端口不同 ( http:// 默认端口是80) |
http://news.company.com/dir/other.html | 失败 | 主机不同 |
源的继承
在页面中通过 about:blank 或 javascript: URL 执行的脚本会继承打开该 URL 的文档的源,因为这些类型的 URLs 没有包含源服务器的相关信息。
IE 中的特例
Internet Explorer 的同源策略有两个主要的差异点:
授信范围
(Trust Zones):两个相互之间高度互信的域名,如公司域名(corporate domains),则不受同源策略限制。端口
:IE 未将端口号纳入到同源策略的检查中,因此 https://company.com:81/index.html 和 https://company.com/index.html 属于同源并且不受任何限制。
这些差异点是不规范的,其它浏览器也未做出支持,但会助于开发基于window RT IE的应用程序。
同源策略官方介绍
跨域解决方案
<script>、<img>、<iframe>、<link>
这些包含 src 属性的标签可以加载跨域资源。但浏览器限制了JavaScript的权限使其不能读、写加载的内容- JSONP
- Nginx代理
- 后台设置
- vue前端代理
JSONP(前端实现
JSONP 是什么
JSONP(JSON with Padding)是JSON的一种补充使用方式,不是官方协议,而是利用 Script 标签请求资源可以跨域的特点,来解决跨域问题的,是一种变通的解决方案。
使用 JSONP,需要服务器后台改动
JSONP 实现原理
JSONP请求的类型是JavaScript脚本(callback 作为前后端的约定,callback的值做为方法名,json内容作为方法的参数),而XHR请求的类型是json类型。
下图是实现代码
$.ajax({
url: 'http://www.baidu.com:8080/login',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
jsonpCallback: "onBack", // 自定义回调函数名
data: {}
});
后端实现(SpringBoot)
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
//设置允许跨域的路径
registry.addMapping("/**")
//设置允许跨域请求的域名
.allowedOrigins("*")
//是否允许证书 不再默认开启
.allowCredentials(true)
//设置允许的方法
.allowedMethods("GET", "POST")
//跨域允许时间
.maxAge(3600);
}
}
Nginx代理
nginx监听8081端口,将前端从nginx监听的端口8081请求过来的请求,代理转发到8080端口(8080为后端接口)
server{
listen 8081;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /Auth {
proxy_pass http://localhost:8080;
}
location /User {
proxy_pass http://lacalhost:8080;
}
}
vue前端代理
vuecli3 在vue.config.js中配置devServer下得proxy
devServer: {
proxy:{
'/admin': {
target: 'http://xxxx.xxxx.cn/',
changeOrigin: true,
pathRewrite: {
'^/admin': ''
}
}
},
port: port,
open: true,
},
Vue 3 + Typescript + Vite 项目中实现在vite.config.ts 文件中修改server下得proxy
server: {
host: '0.0.0.0',
port: 3000,
open: true,
https: false,
proxy: {
'/api': {
target: "https://xxxx.com/",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
版权声明:本文为weixin_43365995原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。