饥人谷技术博客

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

2019-06-01  本文已影响6人  YYPL
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
版权声明:本文为博主原创文章,未经博主许可不得转载

上一篇下一篇

猜你喜欢

热点阅读