跨域问题:
1、同源指的是两个URL的协议、主机名、端口号完全一致,反之则是跨域
2、浏览器允许发起跨域请求,但跨域请求回来的数据,会被浏览器拦截,无法被页面获取到
3、出现跨域的根本原因:浏览器的同源策略不允许非同源的URL之间进行资源的交互
三种跨域的区别:
1、JSONP不是真正的Ajax技术,只是用src绕过了同源策略,CORS是突破了同源策略的限制发起的是真正的Ajax请求
2、JSONP仅支持GET请求,CORS支持各种Ajax请求方式
3、CORS需要由后端开启
4、代理转发是:代理服务器 向 数据服务器(目标服务器) 发起请求,获取数据后代理服务器 和 前端项目同源,所以没有跨域问题,可以直接将数据响应给浏览器
1、jsonp
1、jsonp仅支持GET请求,JSONP 方案没有用到 XMLHttpRequest 对象,因此,JSONP 不是真正的 Ajax 技术
2、JSONP 在底层,用到了 <script> 标签的 src 属性!而src属性不受浏览器同源策略的限制,JSONP是把非同源的 JavaScript 代码请求到本地,并执行
3、jsonp动态地从服务器请求一个JS文件下来,只不过,请求回来的JS文件中的代码比较特殊,是一个函数的调用
4、程序员必须在客户端声明一个对应的函数,而且我们自己声明的函数的名字,必须和服务器返回的函数名保持一致
5、如果服务器返回的js代码中,在调用函数的时候,传递了参数,则程序员自己定义方法的时候,需要通过形参进行接收
6、这个接收到参数值,就是服务器响应给客户端的数据
封装jsonp
function jsonp(option){
let script = document.createElement('script');
let fnName = "wangxiaoyu" + Math.random().slice(2);
window[fnName] = option.success;
script.src = option.url + "?callback=" + fnName;
document.head.appendChild(script)
script.onload = function(){
script.remove();
delete window[fnName];
}
}
2、CORS
1、是W3C官方标准,支持GET、POST、PUT、DELETE、PATCH等常见的请求方式,不兼容某些低版本浏览器,只需要后端开启CORS即可,前端不用做任何改动
2、CORS 方案用到了 XMLHttpRequest 对象,发起的是纯正的 Ajax 请求
3、CORS 技术需要浏览器和服务器同时支持,二者缺一不可:
① 浏览器要支持 CORS 功能(主流的浏览器全部支持,IE 不能低于 IE10)
② 服务器要开启 CORS 功能(需要后端开发者为接口开启 CORS 功能)
4、服务器端通过 Access-Control-Allow-Origin 响应头,来告诉浏览器当前的 API 接口是否允许跨域请求。
3、代理转发 (proxy)
原理:
跨域只存在与浏览器和服务器之间
服务器与服务器之间不存在跨域的
所以,我们架设一个中间服务器,中间服务器向目标服务器发请求
中间服务器和本地项目同源,中间服务器将数据进行转发,交给本地项目使用
vue-cli已经为我们内置了该技术,我们只需要按照要求配置一下即可。
流程:
1、首先将(.env.development)请求的基准地址换为 '/api',这样就会触发代理机制
# just a flag
ENV = 'development'
# 配置一个端口
port = 7777
# 开发环境的基础地址
VUE_APP_BASE_API = '/api'
2、配置 vue.config.js 中的 devServer
// proxy 单词必须小写
proxy: {
// 判断请求的基准地址是否以 /api 开头,如果是就会触发代理机制
'/api': {
// 目标服务器,就是指向哪个接口地址发送请求(代理服务器的地址,开发环境)
// 在触发 代理准发机制后,请求的基准地址会拼接到 target 地址后面
// http://localhost:3000
target: 'http://localhost:3000',
changeOrigin: true // 是否跨域,如果设置为 true,就能够向目标服务器发起跨域请求
}
}
3、因为地址后面拼接了 /api ,所以请求(比如api/user.js)不必带 /api
/**
* @description 登录接口
* @param {*} data mobile,password
* @returns Promise
*/
export function login(data) {
return request({
url: '/sys/login',
method: 'POST',
data
})
}
4、使用w2代理
1、安装证书(如果需要的话,基本不需要)
2、随便打开一个窗口开启w2
3、开启代理
4、打开网页,设置代理,打开代理地址即可