一、什么是跨域
浏览器出于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。同源策略是一个安全策略。所谓的同源,指的是协议,域名,端口相同。
跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。
二、解决方法
1.JSONP
原理:
利用<script>标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的JSON数据。JSONP请求一定需要对方的服务器做支持才可以。SONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅仅支持get方法具有局限性,不安全可能会遭受XSS攻击。
JSONP流程:
- 声明一个回调函数,其函数名当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)
- 创建一个 <script src=>标签 ,把那个跨域的API数据接口地址,赋值给script的src, 还要在这个地址中向服务器传递该函数名(可以通过问号传参?callback=fn)。
JSONP封装:
// 封装 JSONP函数
function jsonp({ url, params, callback }) {return new Promise((resolve, reject) => {let script = document.createElement('script');params = JSON.parse(JSON.stringify(params));let arrs = [];for (let key in params) {arrs.push(`${key}=${params[key]}`);}arrs.push(`callback=${callback}`);script.src = `${url}?${arrs.join('&')}`;document.body.appendChild(script);window[callback] = function (data) {resolve(data);document.body.removeChild(script);}})
}
// 前端调用
jsonp({url: 'http://localhost:3000/say',params: {wd: 'I Love you'},callback: 'show'
}).then(data => {console.log(data)
})
2.CORS
原理:
跨域资源共享(Cross-Origin Resource Sharing)是一种机制,它使用额外的 HTTP 头部告诉浏览器可以让一个web应用进行跨域资源请求。
实现方式:
CORS需要浏览器和后端同时支持,实现CORS通信的关键是后端。只要后端实现了CORS,实现了跨域。服务端设置 Access-Control-Allow-Origin 就可以开启CORS。该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。
虽然设置CORS和前端没有什么关系,但是通过这种方式解决跨域问题的话,会在发送请求时出现两种情况,分别为简单请求和复杂请求。
简单请求:同时满足1、使用(GET、POST、HEAD)。2、Content-Type 为(text/plain、multipart/form-data、application/x-www-form-urlencoded )。
复杂请求:不是简单请求就是复杂请求了。复杂请求的CORS请求,会在正式通信之前,增加一次HTTP查询请,称为"预检"请求,该请求是option方法的 , 通过该请求来知道服务端是否允许跨域请求。