文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

简单易懂的JSONP和CORS跨域方案详解

2022-11-13 18:13

关注

一、了解跨域

?何为跨域

那为什么拦截呢,我们应该先了解一下什么是同源策略

具体的限制(三限制):

能使的标签(能跨域请求资源的标签):

那你限制了我这么多东西,我要正常使用肯定要跨域喽

?何为同源

如果两个 URL 的协议(Protocol),域名(domain),端口(port)都相同的话,则这两个 URL 是同源

举个例子: 我们寻找跟掘金首页:https://jbzj.cn/同源的URL

URL结果原因
http://jbzj.cn/不同源协议不同
https://jbzj.my.cn/不同源域名不同
https://jbzj.cn:3030/不同源端口不一样(https默认443端口)
https://jbzj.cn/user/2375390426313406同源只有路径不一样
https://jbzj.cn/post/7151609034699718692同源只有路径不一样

小结:跨域的出现是因为浏览器的同源策略对不同协议,域名,端口的URL在DOM对象的读写,Cookie等数据的获取,Ajax请求等方面有限制

二、跨域解决方案

JSONP(JSON with Padding)

?简单实现

  <script>
    function jsonp(){
      return new Promise((resolve, reject) => {
      //在全局定义一个doSomething的函数
        window['doSomething'] = function(data) {
          resolve(data); 
        }
      })
    }
    jsonp().then(res=>{
    //调用doSomething之后会在这里打印
      console.log(res)
    })
  </script>
  //使用script标签向后台/test路径发送参数callback为doSomething
  <script src="http://localhost:3000/test?callback=doSomething"></script>
app.get('/test',(req, res) => {
    //通过res.send()方法-将处理好的内容,发送给客户端
    let { callback } = req.query;
    //返回一个函数的执行式doSomething(‘参数')
    res.send(`${callback}('这里是某车在使用简单的JSONP')`)
})

?流程图

?封装

但是在真正的开发中,我们不可能写一堆<script>标签在那里,所以我们需要对jsonp进行封装

    function jsonp({url, params, callback}){
      return new Promise((resolve, reject) => {
      //动态创建script标签
        let script = document.createElement('script');
        //处理传入的参数
        params = {...params, callback};
         //转换参数表达式
        let arr = []
        for(let key in params) {
          arr.push(`${key}=${params[key]}`)
        }
        //在路径中,参数用 & 隔开
        script.src = `${url}?${arr.join('&')}`
        //添加 script 标签
        document.body.appendChild(script);
        //声明回调函数
        window[callback] = function(data) {
        //执行异步函数
          resolve(data);
          //请求完后移除该script标签
          document.body.removeChild(script)
        }
      })
    }
   jsonp({
      url:'http://localhost:3000/test',
      params:{ args:'这个是参数' },
      callback: 'doSomething'
    }).then(res=>{
      console.log(res) 
    })

?优缺点

CORS(Cross-Origin Resource Sharing)

简单请求

判定:

请求方法是以下方三种方法之一

请求头仅包含安全的字段,如以下几种字段

请求过程

    btn.addEventListener('click',()=>{
      const xhr = new XMLHttpRequest();
      xhr.open('get', 'http://localhost:3000/test'); //向端口号为3000的发起请求
      xhr.send();
      xhr.onreadystatechange = function(){
        if(xhr.readyState == 4) {
          if(xhr.status >= 200 && xhr.status < 300) {
            console.log(xhr.response) //如果请求成功,则打印后台返回的数据
          }
        }
      }
    })
app.get('/test',(req,res)=>{
    //通过res.send()方法-将处理好的内容,发送给客户
    res.send(`你好呀某车,你已经成功发起请求了`)
})

app.all("*",function(req,res,next){
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin","http://127.0.0.1:5500");
    res.header("Access-Control-Allow-Methods",'PUT,POST,GET,DELETE,OPTIONS')
    next();
})

复杂请求

请求过程

我们依旧使用上面的代码,然后就请求方式改为put,此时发送的即为复杂请求,可以看到发送了两次请求,由于我们put方法在上述已经被设置为可访问的方法,所以现在预检可以通过,我们也能正常请求到资源

如果我们将put方法从Access-Cntrol-Allow-Methods移除,此时再进行请求,则发提示,在预检请求中发送PUT方法是不被允许的

此时test正式请求则报CORS错误

写到这里,我就想到了曾经看过的面试题:跨域请求如何携带cookie

扩展

    const xhr = new XMLHttpRequest();
    xhr.withCredentials = true;
    res.header("Access-Control-Allow-Credentials", "true");

缺点

IE10以下不支持

小结:后端是关键,主要是设置Access-Control-Allow-Origin

关于postMessage和webSocket的跨域方案我写在嗦嗦postMessage和webSocket这里了

以上就是简单易懂的JSONP和CORS跨域方案详解的详细内容,更多关于JSONP CORS跨域方案的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯