跨域知多少
◼️ 为什么会出现跨域问题
跨域是由于浏览器端的同源策略限制所得来,跟服务器端没有关系。
同源策略(Same-origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。
通俗的讲就是当你在本地调试的时候,网页地址为http://localhost:8080, 而后端的接口地址为:https://blog.csdn.net/sunyctf 此类新地址,这时若你想在本地调试正确访问接口地址并拿到接口数据,就会出现跨域问题。(localhost:8080与https://blog.csdn.net/sunyctf非同源地址)
什么是跨域?
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
![](https://img.haomeiwen.com/i27493437/bab1a84f52a238e7.png)
◼️ 浏览器非同源限制带来的问题
❌无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
❌无法接触非同源网页的 DOM
❌无法向非同源地址发送 AJAX 请求
◼️ 为什么需要跨域?
在最一开始,我们知道了,跨域只存在于浏览器端。而浏览器为 web 提供访问入口。我们在可以浏览器内打开很多页面。正是这样的开放形态,所以我们需要对他有所限制。就比如林子大了,什么鸟都有,我们需要有一个统一的规范来进行约定才能保障这个安全性。
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互,这是一个用于隔离潜在恶意文件的重要安全机制。
只要网站的协议protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用,会受到同源策略的限制。浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用(通常指使用 XMLHttpRequest 请求)。
❣️ http-proxy代理跨域
1. CORS、JSONP存在的问题
(1). CORS: 优点: 仅服务器端修改即可; 缺点: 必须知道客户端的具体IP地址
(2). JSONP: 优点: 不需要知道客户端具体IP地址; 缺点: 需要客户端和服务器端都作出调整!
(3). 如果服务器端觉得CORS也不好用,JSONP也不好用,干脆就没有做跨域!单靠前端能否跨域?
2. 前端如何解决跨域
利用vue脚手架中自带的http-proxy代理程序来跨域访问。详细信息可查看官方文档: https://cli.vuejs.org/config/#devserver-proxy
今后,只要别人问你们公司的项目用的什么跨域,都说:http-procy(http代理)
3. 什么是HTTP代理(http-proxy)
在vue客户端项目中,用js临时创建一个小程序,发送http请求(不是ajax)。由这个底层的小程序负责发送请求,接收响应。而客户端vue项目只需要将自己的请求地址交给底层小程序,然后,等着从小程序获取响应结果即可!
4. 如何使用HTTP代理
(1). 在vue脚手架配置文件(vue.config.js)中,添加一个新的配置项
module.exports={
... ... ,
devServer: {
proxy: {
'/api': { // 为所有服务器端接口起一个别名前缀,为了和vue脚手架中其它页面的路由地址区分
target: `http: // 服务器端接口地址统一前缀`, ---要跨域的域名即接口的域名
changeOrigin: true, //是否对服务器隐藏源地址(选为true)
pathRewrite: {
// 因为真实的服务器端地址中是不包含/api的,所以
'^/api' : '' // 应该将程序中的/api删除(替换为空字符串),再和target中的基础路径拼接起来作为发送到服务器的最终请求地址。
}
}
}
}
}
设置代理,通过pathRewrite将代理标识设置为空重写访问路径解决跨域
(2). 在main.js中,axios的baseURL就不能写真实的服务器地址,应该写devServer中定义的所有服务器端地址的别名前缀:
axios.defaults.baseURL="/api"
(3). 在组件内使用axios发送请求时,依然使用接口的相对地址就可以: this.axios.get("/index")
5. proxy实现跨域的原理
this.axios.get("/index")
↓axios会将baseURL和"/index"拼接
this.axios.get("/api/index")
所有↓带有/api前缀的路径都会交给devServer程序处理
devServer —— 不使用ajax,也能发送http请求的程序
↓先将相对路径中的/api去掉
/index
↓再和提前配置好的这是服务器地址target拼接
http://localhost:5050/index
↓向真实的服务器接口地址发送请求
devServer接到响应结果
↓
返回给axios.then(result=>{})继续处理
整个过程因为没有用到ajax,所以不受浏览器同源策略的限制。
![](https://img.haomeiwen.com/i27493437/e8980cc964f08df1.png)
6. 强调:使用proxy有前提
只有访问没有启用跨域的服务器端时,才能使用http-proxy。不能和其它跨域方式并存的。
网友评论