跨域八股文与vue项目中的实际应用

什么是跨域

跨域的产生是因为浏览器的同源策略问题,同源策略是指请求的url地址,必须与浏览器上的url地址的协议名(http,https),域名,端口号(8080)都一样的情况下,才允许访问相同的cookie或是Ajax请求等,如果在不同源的情况下访问这些请求,就称为跨域;
有三个标签支持跨域加载资源:

跨域的方式

vue中实现跨域的方法:

(1) 后端设置允许跨域访问:在生产环境下建议不要设置允许跨域访问或者限制允许跨域的IP
(2) 前端通过代理proxy进行访问后端
配置vue-cli代理访问,比如配置2个请求的后端,分别是
请求http://localhost:4201/adminapi/会代理请求http://localhost:8180/
请求http://localhost:4201/portalapi/会代理请求http://localhost:8185/
因为vue-cli是基于webpack,所以webpack的devServer选项都是支持配置的

module.exports = {
    devServer: {
        prot: 4201,
        proxy: {
            "/adminapi": {
                // api服务器的地址
                target: "http://localhost: 8180",
                // 如果是https接口,需要配置这个参数
                secure: true,
                // 如果是websocket接口,需要配置这个参数
                ws: true,
                // 是否跨域
                changeOrigin: true,
                // 重写路径,将"/adminapi"重写为""
                pathRewrite: {
                    "^/adminapi": ""                
                }
            },
            "/portalapi": {
                target: "http://localhost: 8185",
                ws: true,
                changeOrigin: true,
                pathRewrite: {
                    "^/portalapi": ""                
                }
            },                    
        }    
    }
}

proxy代理实现跨域的原理:
vue-cli脚手架工具开发项目时,脚手架工具启动一个本地node服务,这就是开发时预览地址一般是端口号而不是本地文件例如"xx.html"
如果我们的接口地址是/api/user,如果不进行特殊设置,那么ajax请求的地址就是:http://localhost:8888/api/user,
也就是访问的是我们脚手架工具提供的本地的node服务器,如果我们设置了代理,那么本地node服务器收到请求会转发到对应的第三方服务端接口

八股文实现跨域的方法

(1)jsonp:解决跨域请求资源,支持get请求,不支持post请求,ajax直接请求普通文件存在跨域无权限访问的问题,但是在调用js文件又不受跨域影响,比如引入jquery框架,调用图片地址,凡是拥有src属性的标签都可以进行跨域,比如img,scirpt,提供一个script标签,请求页面中的数据,同时传入一个回调函数的名字, 服务端得到名字后执行回调函数,使用远程跨域访问就是将远程服务器数据装入js格式的文件,最后为了方便客户端使用数据形成了jsonp,要点是允许用户传递一个callback参数给服务端

script标签不受策略影响,可以动态生成script去请求数据,但是仅限于Get请求
// 原生实现方法
  	var script = document.createElement('script');
  	script.type = 'text/javascript';   
  	// 传参并指定回调执行函数为onBack
  	script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';    
  	document.head.appendChild(script);    
 	 // 回调执行函数
 	 function onBack(res) {
  	  alert(JSON.stringify(res));
 	 } 
// vue实现
  	this.$http.jsonp(
  'http://www.domain2.com:8080/login', 
   { params: {},    
     jsonp: 'onBack'
   }
).then(res => { console.log(res) }
)

(2)domain:通过修改documen的domain属性,可以实现域和子域或者不同子域之间的传值,根据同源策略认为域和子域属于不同的域,比如www.baidu.com和sub.baidu.com是不同的域,我们无法在www.baidu.com中调用sub.baidu.com中定义的js方法,但是我们将document中domain属性改为baidu.com,浏览器就会默认他们在同一个域下,就能完成通信传值

仅限主域相同,子域不同的跨域应用场景,两个页面都通过js强制设置document.domain为基础主域,就实现了同域
<!-- 父窗口:http://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>

<!-- 子窗口:http://child.domain.com/b.html -->
<script>
  document.domain = 'domain.com';    
  // 获取父窗口中变量
  alert('get js data from parent ---> '+ window.parent.user);
</script>

(3)cors:跨域资源共享,支持get,post,head三种http请求方式,允许浏览器跨服务器发起XMLHttpRequest请求,从而解决Ajax只能永远同源使用的限制,整个通信过程由浏览器自动完成不需要用户参与,当浏览器发现AJAX请求资源,就会自动添加一些请求头信息,服务器根据需求配置CORS响应头信息,用户不会察觉,需要浏览器服务器同时支持,IE10以下不支持,关键是服务器,服务器实现cors接口,就能实现跨域通信;比如端口号不同,一个为3000,一个为5000,3000要访问5000端口号内部的js定义方法,可以在5000的服务器响应头添加Access-Controller-Allow-Origin属性:地址,指定同源策略地址,浏览器检测到响应头上带了CORS与本网站,就不会拦截请求响应

目前主流的跨域解决方案,服务端设置Access-Controller-Allow-Origin属性即可,若带cookie请求则
前后端需求设置
    前端:检查设置是否带cookie: xhr.withCredentials = true,此方式发起请求会出现简单请求和复杂请求
    简单请求:Content-Type的值为text/plain, multipart/form-data
,application/x-www-form-urlencoded
    复杂请求:会在正式通信前增加一次HTTP查询请求(预检),通过option方法通过请求知道服务端是否允许跨域请求
    Options预检请求:
请求头:(1)origin: 当前请求源,和响应头里的Access-Control-Allow-Origin 对标, 是否允许当前源访问,Origin是不可修改的
(2)Access-Control-Allow-Origin:本次真实请求的额外请求头,和响应头里的Access-Control-Allow-Headers对标,是否允许真实请求的请求头
(3)Access-Control-Request-Method:本次真实请求的额外方法,和响应头里的Access-Control-Allow-Methods对标,是否允许真实请求使用的请求方法

(4)window.name + iframe跨域
适合单向数据跨域请求,当window的location发送变化,重新加载页面时,name属性保持不变,可以在页面A中用iframe加载其他域的页面B,页面B通过js操作将需要传递的数据赋给window.name,iframe加载完成后,页面A修改iframe的地址将其编程同域就可以进行访问

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值