美文网首页饥人谷技术博客
跨域解决方案实践(1)JSONP

跨域解决方案实践(1)JSONP

作者: YYPL | 来源:发表于2019-06-01 00:59 被阅读6次
    JSONP.jpg

    什么是JSONP

    <script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
    上面的代码就是我们经常用到的引入jquery的方式,HTML 中 script 标签可以加载其他域下的js,因此利用这个特性实现从非同源的域获取数据

    JSONP是通过 script 标签加载数据的方式去获取数据当做 JS 代码来执行提前在页面上声明一个函数,函数名通过接口传参的方式传给后台,后台解析到函数名后在原始数据上「包裹」这个函数名,发送给前端。因此,JSONP 需要对应接口的后端的配合才能实现。

    JSONP绕开同源限制的具体操作

    发送的ajax请求到达后端服务器后,后端会去解析callback这个参数获取到字符串appendHtml,在发送数据做如下处理:
    后端返回数据:

    appendHtml([
            "姓名:库里",
            "场均出场时间:36分钟",
            "场均得分:32.5",
            "有效命中率:61%"
            ]
        ) 
    

    前端script标签在加载数据后会把 appendHtml()做为 js 来执行,这实际上就是调用appendHtml()这个函数,同时参数是server-json.jsPlayerData 。 用户只需要在加载提前在页面js中定义好appendHtml()这个全局函数,在函数内部处理参数即可。

    代码
    用node.js构建一个简单后端服务器

    server-jsonp.js如下:

    var http = require('http') 
    var path = require('path')
    var url = require('url')
    var fs = require('fs')
    
    var server = http.createServer(function(req, res){
      // 返回的URL对象的query属性会是一个使用querystring模块的parse()生成的对象
      var pathObj = url.parse(req.url, true)
      // pathObj.pathname 相当于document.location.pathname
      // console.log('Path-Name: ',pathObj.pathname)
      switch (pathObj.pathname) {
        case '/getData':
          var PlayerData = [
            "姓名:库里",
            "场均出场时间:36分钟",
            "场均得分:32.5",
            "有效命中率:61%"
            ]
        
          // 没有callback这个参数就直接把发送回去(响应体)
          if(pathObj.query.callback){
            res.end(pathObj.query.callback + '(' + JSON.stringify(PlayerData) + ')')
          }else{
            // 没有没有callback这个参数就直接把发送回去
            res.end(JSON.stringify(PlayerData))
          }
          break;
        default:
          fs.readFile(path.join(__dirname, pathObj.pathname), function(e, fileContent){
            if(e){
              res.writeHead(404, 'not found')
              res.end('<h1>404 Not Found</h1>')
            }else{
              // 相当于res.write(fileContent); res.end()
              res.end(fileContent)
            }
          }) 
      }
    })
    server.listen(8080)
    

    index.html如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>JSONP跨域测试</title>
    </head>
    <body>
      <div class="container">
        <button class="display">球员数据</button>
        <ul class="info">
        </ul>
      </div>
      <script>
        function $(selector) {
          return document.querySelector(selector)
        }
    
        $('.display').addEventListener('click', function(){
        var script = document.createElement('script')
        // localhost 是一个域名,在过去它指向 127.0.0.1 这个IP地址
        script.src = 'http://127.0.0.1:8080/getData?callback=appendHtml'
        document.head.appendChild(script)
        document.head.removeChild(script)
      })
        // appendHtml处理服务器返回给浏览器的数据,绕开同源
        function appendHtml(PlayerData) {
          var html = ''
          for(var i = 0; i < PlayerData.length; i++) {
            html += '<li>' + PlayerData[i] + '</li>'
          }
          console.log(html)
          $('.info').innerHTML = html
        }
      </script>
    </body>
    </html>
    
    1. 在终端或是Iterm工具中打开目标文件夹
    2. 键入node server-jsonp.js ,启动服务器
    3. 在浏览器地址栏输入http://localhost:8080/index.html
    4. 打开控制台,cmd + r刷新网页
    未点击球员数据button
    JSONP跨域-1.png
    点击球员数据button
    JSONP跨域-2.png
    通过上面的图片可以清晰的看出,服务器把数据PlayerData传递给了浏览器,然后调用函数appendHtml()参数为PlayerData,做种显示的效果表示数据已经跨域成功

    JSONP的优点

    JSONP并不是新的技术,易理解,通过巧妙地方法绕过同源,运用的还是过往的js基础知识,学习成本低


    参考:

    阮一峰JavaScript教程
    node.js打造你的简单服务器
    Node.js api 文档
    JSONP
    版权声明:本文为博主原创文章,未经博主许可不得转载

    相关文章

      网友评论

        本文标题:跨域解决方案实践(1)JSONP

        本文链接:https://www.haomeiwen.com/subject/edintctx.html