跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 javascript 施加的安全限制。
同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域。
作者信息
github: https://github.com/Michael-lzg
掘金: https://juejin.im/post/
虽然现在大部分项目并不会使用它来解决跨域,但是只要是面试,涉及到跨域,基本都会问到这个知识点。他说利用 script 标签天然跨域的特性。
缺点:只能使用 get 请求,不推荐使用
原生实现
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
document.head.appendChild(script);
// 回调执行函数
function handleCallback(res) {
alert(JSON.stringify(res));
}
</script>
<!-- 服务端返回如下(返回时即执行全局函数): -->
handleCallback({"status": true, "user": "admin"})
复制代码
jquery ajax:
$.ajax({
url: 'http://www.demo2.com:8080/login',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
jsonpCallback: 'onBack', // 自定义回调函数名
data: {}
})
vue.js:
this.$http
.jsonp('http://www.demo2.com:8080/login', {
params: {},
jsonp: 'onBack'
})
.then(res => {
console.log(res)
})
使用 web 服务器的反向代理设置,这不是前后端跨域解决方案,而是属于运维层级的。
1、nginx配置解决iconfont跨域 浏览器跨域访问js、css、img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置。
location / {
add_header Access-Control-Allow-Origin *;
}
2、nginx反向代理接口跨域 跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
#proxy服务器
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
index index.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}
当下项目中如果涉及到跨域,实际上都应该是后端通过设置 CORS 来解决的。CORS 是目前最主流的跨域解决方案,跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的 Web 应用被准许访问来自不同源服务器上的指定的资源。
// 在node端设置一下请求头,允许接收所有源地址的请求
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
res.header('Access-Control-Allow-Headers', '*')
利用 node + webpack + webpack-dev-server 代理接口跨域。在开发环境下,由于 vue 渲染服务和接口代理服务都是 webpack-dev-server 同一个,所以页面与代理接口之间不再跨域,无须设置 headers 跨域信息了。webpack.config.js 部分配置:
module.exports = {
entry: {},
module: {},
...
devServer: {
historyapiFallback: true,
proxy: [{
context: '/login',
target: 'http://www.demo2.com:8080', // 代理跨域目标接口
changeOrigin: true,
secure: false, // 当代理某些https服务报错时用
cookieDomainRewrite: 'www.demo1.com' // 可以为false,表示不修改
}],
noInfo: true
}
}
此方案仅限主域相同,子域不同的跨域应用场景。
实现原理:两个页面都通过 js 强制设置 document.domain 为基础主域,就实现了同域。
父窗口:(www.domain.com/a.html)
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
document.domain = 'domain.com'
var user = 'admin'
</script>
子窗口:(child.domain.com/b.html)
<script>
document.domain = 'domain.com'
// 获取父窗口中变量
alert('get js data from parent ---> ' + window.parent.user)
</script>
postMessage 是 HTML5 XMLHttpRequest Level 2 中的 API,且是为数不多可以跨域操作的 window 属性之一,它可用于解决以下方面的问题:
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe')
iframe.onload = function() {
var data = {
name: 'aym'
}
// 向domain2传送跨域数据
iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com')
}
// 接受domain2返回数据
window.addEventListener('message',function(e) {
alert('data from domain2 ---> ' + e.data)
},false)
</script>
b.html:(www.domain2.com/b.html)
<script>
// 接收domain1的数据
window.addEventListener('message',function(e) {
alert('data from domain1 ---> ' + e.data)
var data = JSON.parse(e.data)
if (data) {
data.number = 16
// 处理后再发回domain1
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com')
}
},false)
</script>
web前端的同学如果使用ajax,如果请求后端地址和页面访问的地址“URL的首部”不同就会出现访问被拒绝的情况,这就需要跨域来解决前后端的通讯问题,下面将列举一些在实际项目中应用也是比较多的方法。
利用js动态创建一个link插入到文档中, 请求css文件,利用 computedStyle = window.getComputedStyle 获取指定元素的 style 对象,利用 computedStyle .content 获取内容
XMLHttpRequest对象(IE中为XMLHTTP对象)是AJAX应用的核心。由于现代浏览器对跨域请求的限制,在使用时需多加注意。本教程尽量用简单易懂的话描述(跨域)问题,并提供一个方案:通过Web代理(Web Proxy)
Jsonp原理是动态创建一个script标签,利用script标签src属性访问没有限制,实现跨域。Ajax是页面无刷新请求数据操作,Jsonp不是真正的ajax请求。讲解Ajax 和 jsonp的区别,在jquery中使用jsonp
JSONP方案:前端提供 API 的方法,其实解耦还没有解的很干净,我们在设置script的src时直接给它传参,后端插入这个参数这就可以了。因为JSONP是通过动态创建Script实现的,动态创建Script只有GET请求没有POST请求
浏览器的同源策略会导致跨域,这里同源策略又分为以下两种:DOM同源策略、XmlHttpRequest同源策略。只要协议、域名、端口有任何一个不同,都被当作是不同的域,之间的请求就是跨域操作。
在开发静态页面时,类似Vue的应用,我们常会调用一些接口,这些接口极可能是跨域,然后浏览器就会报cross-origin问题不给调。最简单的解决方法,就是把浏览器设为忽略安全问题,设置--disable-web-security。
此方案只能用于开发环境,线上最好设置同源策略(遇到个后端,装你妈批),前后端不在同一服务器的情况下,前端要访问后端API,可通过在vue.config.js中配置代理服务器。
在使用vue.js开发前端项目时,再结合webpack搞起各种依赖、各种插件进行开发,无疑给前端开发带来了很多便捷,就在解决跨域这个问题上,相信众多用vue.js的前端同僚们同我一样尝到了甜头
正向代理是你发出请求的时候先经过代理服务器,所以实际上发出请求的是代理服务器。反向代理是“代理你的目标服务器”,请求目标服务器的代理,做一些处理后再真正请求。在这篇文章里,反向代理用于处理跨域问题。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!