前端线上课丁鹿学堂:jsonp跨域详解

69 阅读1分钟
jsonp到底是什么?

在面试的时候问跨域怎么解决,通常第一个回答就是jsonp,虽然工作中不常用,但是没有弄懂总是会觉得心里没底。今天就利用nodejs来从前端到后端完全弄明白,什么是jsonp。

Web页面上调用js文件时则不受是否跨域的影响,其实,凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>

所以就有人利用这个特性实现跨域传递数据。我们可以调用跨域服务器上动态生成的js格式文件,也就是调用JSON文件,获取自己需要的数据。

后来逐渐形成了一种非正式的传输协议,也就是JSONP。该协议允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,客户端接收到响应后执行回调并且可以对数据进行各种需要的处理。

jsonp跨域原理: 动态创建script标签,利用script标签的src属性没有跨域限制,我们在前端提前定义好一个函数名(约定俗成为callback),后端返回的是一个callback() 形式的代码片段, 前端定义一个函数名相同的函数,此时可以拿到这个函数的参数,就是要获取的数据。 jsonp的优点: JSONP可以跨越同源策略,实现跨域传输 JSONP兼容性更好,在更加古老的浏览器中都可以运行 在请求完毕后可以通过调用callback的方式回传结果。将回调方法的权限给了调用方 jsonp的缺点: 只支持get请求。 安全性不高。如果提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的,那么所有调用这个jsonp的网站都会存在漏洞 实现: 前端:

    <script>
        let oScript = document.createElement('script')
        oScript.src = 'http://localhost:3000/api/getValue?callback=getValue'
        document.body.appendChild(oScript)
        function getValue(data){
            console.log(data) //{name: 'zhangsan', age: 18}
        }
    </script>

后端:

let http = require('http')
let url = require('url')
http.createServer((req,res)=>{
  let data = url.parse(req.url,true)
  console.log(data)
  let callback = data.query.callback
  if(data.pathname === '/api/getValue'){
    res.end(`${callback}(${JSON.stringify({
      name:'zhangsan',
      age:18
    })})`)
  }else{
    res.end("404")
  }
}).listen(3000,()=>{
  console.log('server run ...')
})