JSONP是什么

查资料的解释: JSONP数据交互协议一般用于Ajax跨域请求。Ajax直接请求普通文件存在跨域无权限访问的问题,然而web页面上调用js文件则不受是否跨域的影响(凡是拥有src该属性的标签都有跨域的能力),于是通过web端跨域访问数据的时候,设法把数据装进js格式的文件里面。获取之后便可以在web端进一步进行处理。
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一 个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了
jsonp的整个过程就类似于前端声明好一个函数,后端返回执行函数。执行函数参数中携带所需的数据

个人理解:即就是因为我们在数据交互的时候需要的数据是需要跨域的,但是我们常用的ajax又不支持跨域请求,所有jsonp诞生了,jsonp就是一种非正式的传输协议,即通过web页面在调用js时可以跨域这个特点,我们把我们需要的数据放在远程服务端的js格式的文件里,这样web端 就可以获取了,获取后如何处理数据就是web端的事情,即可以写一个函数来处理,在后端调用这个函数就可以了,但是这个方法一个难点就是因为请求的时候我们每次使用这个jsonp是需要调用的函数的名字是不一样的,即我们可以在让这个函数的名字动态生成,然后再把这个名字传入后端执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function jsonp(option) {
      // 将用户通过对象命名空间传递进来的函数挂载到全局
      var callbackName = 'itcast_' + Math.random().toString().substr(2) + Math.random().toString().substr(2)
      !window.callbacks && (window.callbacks = {})
      window.callbacks[callbackName] = function (data) {
        option.success(data)
        // 这里才意味着可以删除 script 标签了
        // 这里可以直接使用 script ,原因是下面的变量提升,而且等这里使用 script 的时候,下面的代码早就执行结束了
        document.body.removeChild(script)
      }
      // 1. 解决 url 问题
      // 2. 解决回调处理函数问题
      option.url = option.url + '?callback=callbacks.' + callbackName
      //这里就是将动态生成的函数名通过URL路径传给后端(callbacks对象中的callbackName属性)
      //即因为jsonp只支持get方法,就需要把数据写入到url中
      var script = document.createElement('script')
      script.src = option.url
      // 将 script 上到 DOM 中
      document.body.appendChild(script)
    }
    服务端:
    const express = require('express')
    const app = express()
    app.get('/', (req, res, next) => {
  console.log(`收到客户端请求了:${req.url}`)
  var data = JSON.stringify({
    foo: 'bar',
    list: [1, 2, 3]
  })
  setTimeout(function () {
    res.end(`${req.query.callback}(${data})`)
  }, 1000)//获取路径的callback中的函数名,然后执行此函数
})

app.listen(3000, () => {
  console.log('running...')
})