json

117 阅读1分钟

知识补充:jsonp

script标签请求到的内容会自动执行,请求回来的回调函数的调用,后端是将把函数的调用和参数一并返回,一个简单的字符串拼接函数

res.end('test({"name": "sxy"})');

前端请求回来了'test({"name": "sxy"})',再执行函数,即可完成函数执行

乞丐版

//page..
const jsonFn = ({ name, age }) => { console.log(name, age) }
function createJSONP(url, callback) {
  var script = document.createElement("script");
  script.src = `${url}?callback=jsonFn` 
  document.body.append(script);
}
createJSONP("http://localhost:5000")
​
//服务端server.js
const express = require('express');
const app = express();
app.use('/', function (req, res) {
  const { callback } = req.query;
  const info = {name: 'sxy', age: 22};
  res.send(`${callback}(${JSON.stringify(info)})`);
});
app.listen(5000, () => console.log('5000 port has listen'));

包装后的jsonp函数

function createJSONP(url, callback) {
  const script = document.createElement("script");
  script.src = `${url}?callback=${callback}`
  script.id = "script"
  return new Promise((resolve, reject) => {
    try {
      document.body.appendChild(script);
      window[callback] = (res) => resolve(res)
    } catch (err) {
      reject(err)
    } finally {
      document.body.removeChild(script)
    }
  })
}
createJSONP("http://localhost:5000", "fn").then(console.log)

同异步相关

默认的script标签是同步的,也就是当碰到script标签,会请求资源,写在script之前的html会被渲染一遍,等script加载完毕,在渲染后面的html

① async: 异步加载对应的javascript脚本,不阻塞HTML页面的渲染,当对应的javascript加载完成后,如果此时HTML页面还未加载完成,那么会阻塞页面的渲染等javascript执行完成后再继续HTML页面的加载

② defer: 异步加载对应的javascript脚本,不阻塞HTML页面的渲染,当对应的javascript加载完成后,如果此时HTML页面还未加载完成,那么不会阻塞页面的渲染等HTML页面加载完成后再接着执行加载完成的javascript脚本

③ type="module" : 也是能起到异步加载的效果,效果同defer,不过其可以配合async属性让javascript加载完成后立即执行