前端

前端 JSONP 原理及 Node 模拟 JSONP

2021-08-01  本文已影响0人  弹力盒

1、关于 JSONP 请求的注意项

2、JSONP 实现原理(前端)

/**
 * JSONP 前端原理(具体分为以下四步)
 * JSONP 请求只支持 GET 形式
 */

function getJSONP () {
  /**
   * 第一步
   * 创建一个 script 标签
   */
  const script = document.createElement('script')

  /**
   * 第二步
   * 绑定 script 标签 src 属性
   * 并设置回调函数名(这里为 getData)
   */
  const url = 'http://127.0.0.1:15000/jsonp?callback=getData'
  script.setAttribute('src', url)

  /**
   * 第三步
   * 全局环境下设置回调函数
   * !!! 一定要在全局环境下,getJSONP 函数作用域内不行
   */
  window.getData = function (data) {
    console.log(data)
  }

  // 第四步,在 head 标签下添加上述的 script 标签
  document.getElementsByTagName('head')[0].appendChild(script)
}

// 开始请求
getJSONP()

3、JSONP 实现原理(Node + Express)

const express = require('express')
const app = express()

app.use(express.static('./'))

// 首页展示
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html')
})

/**
 * jsonp 请求 express 写法
 * jsonp 仅支持 GET 请求,由于 script 标签的限制
 */
app.get('/jsonp', (req, res) => {
  res.jsonp({ name: 'hehe' })
})

app.listen(15000, () => {
  console.log('server is running at localhost:15000/')
})

4、成功后,页面 Dom 结构效果

image.png

5、简单封装

/**
 * 简单封装
 * 采用箭头函数形式,声明的 getData 里面的 this => window
 * @param { jsonp 接受属性  } options
 */
const getData = (options) => {
  // 设置 options 的默认属性
  const defaultOptions = {
    callback: 'callback',
    data: {},
    success: function (data) { }
  }

  // 覆盖默认 options 属性
  options = Object.assign(defaultOptions, options)

  // 设置全局回调函数
  window[options.callback] = function (data) {
    options.success(data)
  }

  // 创建 script 标签,并设置其 src 属性
  const script = document.createElement('script')
  const url = `
    http://127.0.0.1:15000/jsonp?callback=
    ${options.callback}${formatParams(options.data)}
  `
  script.setAttribute('src', url)

  // 将 script 标签绑定到 body 上面
  document.getElementsByTagName('head')[0].appendChild(script)
}

// 格式化 jsonp 请求参数
const formatParams = (params = {}) => {
  let result = ''
  for (const i of Object.entries(params)) {
    result += `&${i[0]}=${i[1]}`
  }
  return result
}

getData({
  callback: 'hahaha',
  data: { param1: 'param1' },
  success: function (data) {
    console.log(data)
  }
})
上一篇下一篇

猜你喜欢

热点阅读