共计 2546 个字符,预计需要花费 7 分钟才能阅读完成。
对于跨域, 每一个前端同学都不陌生, 关于如何解决跨域也有很多种方法, 这里我就总结一下什么是跨域、为什么会跨域以及我常用的解决跨域的几种方式。
跨域
浏览器同源策略: 浏览器 限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
同源策略的具体表现:
1)http 请求不能向不同源的服务器发起 HTTP 请求
2) 非同源的网页不能共享 Cookie、LocalStorage、IndexDB
3)禁止对不同源页面的 DOM 进行操作。主要场景是 iframe 跨域的情况, 不同域名的 iframe 限制相互访问
同源: 请求 URL 地址中的协议、域名及端口号都相同, 只要有一个不相同就是跨域。
例子:
域名: http://www.example.com
跨域请求:
https://www.example.com // 协议不同
http://api.example.com // 域名不同
http://www.example.com:8080 // 端口号不同
解决跨域的常用几种方案
解决方案:
1)jsonp
2)nginx 反向代理
3) 配置 vue-cli 生成的文件实现代理
4) 后端设置 CORS 来解决跨域
注: 二、三两种都是服务器代理, 因为跨域是浏览器的跨域限制, 但是服务器不存在跨域问题, 所以可以由服务器请求所要访问的资源然后再返回给客户端
JSONP
jsonp 实现原理 : <script> 标签不受浏览器同源策略的影响, 允许跨域引用资源。因此可以通过动态创建 script 标签, 然后利用 src 属性进行跨域。
JSONP 实现方式: 动态创建 script 标签, 通过回调函数处理请求结果
JSONP 的优点:
1) 可以跨域
2) 兼容性好
JSONP 的缺点:
1) 只能支持 GET 请求,JSONP 在调用失败时不会反悔各种 HTTP 状态码
2) 安全性。如果提供 JSONP 服务被人控制, 那么所有调用这个 JSONP 的网站都存在漏洞。
下面是通过 JSONP 调用百度搜索的例子:
//HTML
<div class="wrap">
<input type="text">
<ul></ul>
</div>
//JS
let inpEle = document.querySelector('input');
let ulEle = document.querySelector('ul');
let interval = 0;
function searchData(data) {if (data.g) {
let result = data.g;
let fragment = document.createDocumentFragment();
let html = '';
result.forEach((item) => {html += `<li><a target="_blank" href="https://www.baidu.com/s?wd=${item.q}">${item.q}</a></li>`;
} )
ulEle.innerHTML = html;
} else {ulEle.innerHTML = '';}
}
let scriptEle = null;
inpEle.oninput = search;
function search() {
let val = inpEle.value;
let now = new Date().getTime();
if (now - interval > 300) {if (scriptEle) {scriptEle.remove();
}
scriptEle = document.createElement('script');
// wd 后面接的是关键字,cb 后面接的回调函数的名称
let url = 'https://www.baidu.com/sugrec?ie=utf-8&json=1&from=pc_web&prod=pc&wd='+ val + '&req=2&cb=searchData'
scriptEle.src = url;
document.body.appendChild(scriptEle);
}
}
nginx 反向代理
具体配置:
1)安装 nginx: http://nginx.org/en/download….
2)配置要被代理的服务:
在 nginx-1.16.1 ==> conf ==> nginx.conf 里进行配置(代码中找到 server 在里面添加代理即可):
server{
listen 80; // 监听的端口
server_name localhost; // 在浏览器访问的 host-name, 根据这个来判断要代理到什么地方
// 要代理的内容
// 第一步(可以不用) 进行反向代理, 用 localhost:80 来代理 http://127.0.0.1:8081 的请求, 可以根据自己起的本地服务器来进行修改
location / {proxy_pass http://127.0.0.1:8081;}
// 第二步 接口代理, 在 /api 的前面添加添加上指定的域名
location /api {proxy_pass http://1.1.1.1:8080; // 将 /api 的接口反向代理到这个服务器上, 从而实现了跨域}
}
注: 第一步是需要本地用编辑器起一个服务器, 然后 nginx 做反向代理, 从而实现在 80 端口下, 访问非 80 端口的页面, 这个配置完成后, 浏览器的访问地址应该改为 localhost/index.html;若是不想这么麻烦, 可以在先将 nginx-1.16.1 ==> html 下的页面删掉, 然后将代码移动到该位置即可, 访问的地址为 http://localhost/index.html
3)启动 nginx.exe
vue 代理配置
vue 代理配置:
CORS
这个主要是后端做的, 我就不说了, 具体百度就可以。
以上就是我常用的几种跨域解决方案, 如果大家有什么好的方法, 欢迎赐教。
参考资料:
浏览器同源策略及跨域的解决方法: https://www.cnblogs.com/laixi…
MDN 上的同源策略: https://developer.mozilla.org…
MDN 上的 CORS: https://developer.mozilla.org…