为了账号安全,请及时绑定邮箱和手机立即绑定

重学JS(十一)—— 手把手带你跨域

标签:
JavaScript

有一天有人跑来跟我定方案,问我cors是什么原理,一脸懵逼,跨域我只知道jsonP啊,眼看一个装逼的机会就要失去了。
“我现在有点忙,待会找你”。
机智的我马上回到工位,百度百度百度。

同源策略

老生常谈了,不是我家的人,东西当然不能让你随便乱动。
非同源的脚本不能访问或者操作其他域的页面对象(如DOM等),同源策略要求三同, 即: 同域, 同协议, 同端口。

跨域方法

本文只介绍jsonP和cors。

jsonP

<!-- 开发环境版本,包含了用帮助的命令行警告 --><script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

这是vue文档中引入vue.js的方法,可以看到script标签可以直接去请求其他域的JS文件。既然这样,我们就能使用这个特性来实现跨域。

搭个简单服务器

用nodejs+express搭个简单服务器。几行代码足矣。

const express = require('express');const app = express();
app.get('/user',(req,res)=>{  console.log('user');
  res.send(‘success’);
})
app.listen(3000,()=>{  console.log('start');
});

启动服务器。然后写个测试函数,先试试ajax。

function getUserAjax(){  let xhr= new XMLHttpRequest();
  xhr.open("GET","http://127.0.0.1:3000/user",true);
  xhr.send();
}

在chrome控制台下运行getUserAjax函数。


https://img1.sycdn.imooc.com//5d2fc0460001ed1907150058.jpg


可以看到被拒绝了,浏览器没有成功拿到success。这个时候就需要用到jsonP了。因为script标签本身就是可以跨域请求JS文件的。

function getUser(){  let dom = document.createElement('script');
  dom.src = "http://127.0.0.1:3000/user";  document.body.appendChild(dom);
}

控制台下运行getUser()。


https://img1.sycdn.imooc.com//5d2fc04a0001abc604040061.jpg


success没有定义。可见浏览器已经跨域获取到了‘success’。因为script标签加载的JS会立刻执行,而success没有被定义,所以报了这个错。这个时候已经很明了了。前端发请求时将函数名,例如callback传给后台,后台再返回这个函数,callback(info)。这样浏览器接受到数据后,会马上执行callback函数,就像回调函数一样。马上开始改装:
前端代码:

function callback(info){
  alert(info);
}function getUser(){  let dom = document.createElement('script');
  dom.src = "http://127.0.0.1:3000/user?callback=callback";  //url上指明回调函数的名字
  document.body.appendChild(dom);
}

后台代码:

const express = require('express');const app = express();
app.get('/user',(req,res)=>{  let func = req.query.callback;
  res.send(func+'(' + '"success"'+')');
});
app.listen(3000,()=>{  console.log('start');
});

再次执行getUser();成功弹出了success。这就是jsonP的原理。后台返回一个JS函数,带上参数,调用前端准备好的函数。即实现了发请求和回调函数的效果。

cors

这个就更简单了。上面ajax跨域的时候报了这个错误 No 'Access-Control-Allow-Origin' header is present on the requested resource。
那服务器返回的时候带上‘'Access-Control-Allow-Origin' 就好了。他的意思是允许哪些源的请求。你虽然不是我家的人,但这次我信任你,给你个钥匙。
改装下后台代码:

const express = require('express');const app = express();
app.get('/user',(req,res)=>{
  res.header("Access-Control-Allow-Origin", "*");  //设置返回数据的头,代表接受任意源的请求
  res.send('success');
});
app.listen(3000,()=>{
  console.log('start');
});

再在控制台调用上文的getUserAjax()。成功。前端都不用改代码。不过要注意的是cors不是所有的浏览器都会支持。


https://img1.sycdn.imooc.com//5d2fc04f0001c48b06220228.jpg

jsonP和cors比较

cors与jsonP的使用目的相同,但是比jsonP更强大。
jsonP只支持GET请求,cors支持所有类型的HTTP请求。jsonP的优势在于支持老式浏览器,以及可以向不支持cors的网站请求数据。



作者:闪闪发光的狼
链接:https://www.jianshu.com/p/bcc427cf5304


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消