1.什么是跨域?
跨域不是问题,是一种安全机制。
广域的跨域:指一个域下的文档或脚本试图去请求另一个域下的资源。
资源跳转: A链接、重定向、表单提交 资源嵌入: <link>、<script>、<img>、<frame>等dom标签,还有样式中background:url()、@font-face()等文件外链 脚本请求: js发起的ajax请求、dom和js对象的跨域操作等
狭义的跨域:由浏览器同源策略限制的一类请求场景。
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
同源策略限制以下几种行为:
Cookie、LocalStorage 和 IndexDB 无法读取
DOM 和 Js对象无法获得
AJAX 请求不能发送
常见域名场景
URL 说明 是否允许通信
http://www.example.com/a.js
http://www.example.com/b.js 同一域名,不同文件或路径 允许
http://www.example.com/lab/c.js
http://www.example.com:8080/a.js
http://www.example.com/b.js 同一域名,不同端口 不允许
http://www.example.com/a.js
https://www.example.com/b.js 同一域名,不同协议 不允许
http://www.example.com/a.js
http://192.168.1.1/b.js 域名和域名对应相同ip 不允许
http://www.example.com/a.js
http://x.example.com/b.js 主域相同,子域不同 不允许
http://example.com/c.js
http://www.example1.com/a.js
http://www.example2.com/b.js 不同域名 不允许
2.跨域导致的问题
跨域并不会阻止请求的发出,也不会阻止请求的接受,跨域是浏览器为了保护当前页面,你的请求得到了响应,浏览器不会把响应的数据交给页面上的回调,取而代之的是去提示你这是一个跨域数据。提示就是一个报错提示。
报错提示:从某某位置请求的资源被阻挡了,因为没有在响应头里发现:"Access-Control-Allow-Origin"的响应头。
3.三种前端跨域方法
i.跨域资源共享(CORS)(服务端设置,前端直接调用,后台允许前端某个站点进行访问)
普通跨域请求:只服务端设置Access-Control-Allow-Origin
即可,前端无需设置;若要带cookie请求:前后端都需要设置。
通过Access-Control-Allow-Origin
响应头,就告诉了浏览器。如果请求我的资源的页面是我这个响应头里记录了的"源",则不要拦截此响应,允许数据通行。
目前,所有浏览器都支持该功能(IE8+:IE8/9需要使用XDomainRequest对象来支持CORS)),CORS也已经成为主流的跨域解决方案。
安装axios插件
npm i axios --save-dev
引用axios插件
import axios from "axios"
响应代码
let url="跨域接口url"
axios.get(url).then(()=>{})
}
ii.JSONP跨域(前端适配,后端配合,前后台同时改造)
为了减轻服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。
安装jsonp插件
npm i jsonp --save-dev
引用jsonp插件
import jsonp from "jsonp"
响应代码
let url="跨域接口url"
jsonp(url),(err,res)=>{
let result=res;
this.data=result;
}
通过JSONP则不需要Access-Control-Allow-Origin
字段;因为JSONP访问不是一个请求,而是JS脚本。
JSONP缺点:只能实现get一种请求。
iii.代理跨域(访问a接口,代理到b接口;通过修改nginx服务器配置来实现前端修改,后台不动)
类型:1.nginx代理跨域;2.Nodejs中间件代理跨域
创建vue.config.js(webpack的配置表)
//遵循node.js规范,使用module.exports={}
module.exports = {
devServer: {
host: "localhost",//主机
port: 8080,//端口
//代理
proxy: {
//访问a接口,代理到b接口,真正访问b接口
"/api": { //a接口
target: "http://mall-pre.springboot.cn",//b接口
changeOrigin: true, // changeOrigin为是否需要将主机原点改为目标url地址
//设置空的虚拟接口,统一接口,方便拦截
pathRewrite: { //转发地址
api: "",
},
},
},
},
};
更改vue.config.vue的配置信息时,需要重启项目(npm run serve)