美文网首页前端
前端 JSONP 原理及 Node 模拟 JSONP

前端 JSONP 原理及 Node 模拟 JSONP

作者: 弹力盒 | 来源:发表于2021-08-01 14:41 被阅读0次

    1、关于 JSONP 请求的注意项

    • a、JSONP 请求只支持 GET 形式

    • b、JSONP 请求返回的是一个自定义函数,函数名由 callback 传递

    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)
      }
    })
    

    相关文章

      网友评论

        本文标题:前端 JSONP 原理及 Node 模拟 JSONP

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