JSONP,全称JSON with Padding。为解决 GET 请求跨域。
    跨域常用方案:CORS
    JSONP 基于两个原理:

    1. 动态生成 script,使用script.src地址来跨域;
    2. script.src 加载的脚本内容为 JSONP:即 PADDING(JSON) 格式。

    注意:在 GET 的 URL 中,查询参数包含callbackcallback值是一个方法,方法的 形参 就是获取到的服务端数据。

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>简单 JSONP </title>
    8. </head>
    9. <body>
    10. <input type="text">
    11. <button onclick="handleSend()">Send</button>
    12. <ul class="main">
    13. </ul>
    14. <script src="./index.js"></script>
    15. <script>
    16. function handleData(res) {
    17. const liEl = document.createElement('li')
    18. liEl.innerText = res.msg
    19. const ulEl = document.getElementsByClassName('main')
    20. ulEl[0].appendChild(liEl)
    21. const inputEl = document.getElementsByTagName('input')
    22. inputEl[0].value = ''
    23. }
    24. function handleSend() {
    25. const inputEl = document.getElementsByTagName('input')
    26. const sendData = { id: Math.floor(Math.random() * 10), msg: inputEl[0].value || '' }
    27. jsonp({
    28. url: 'http://127.0.0.1:10010',
    29. params: sendData,
    30. onData: handleData
    31. });
    32. }
    33. </script>
    34. </body>
    35. </html>
    1. function stringify(params) {
    2. const obj = Object.entries(params)
    3. const qs = obj.map(([k, v])=> {
    4. let noVal = false
    5. if(v === null || v === undefined || typeof v === 'object') {
    6. noVal = true
    7. }
    8. return `${encodeURIComponent(k)}=${noVal ? '' : encodeURIComponent(v)}`
    9. }).join('&')
    10. return qs
    11. }
    12. function jsonp({url, onData, params}) {
    13. const scriptEl = document.createElement('script')
    14. // 1.函数随机名称,避免全局污染
    15. const cbFnName = 'JSONP_PADDING' + Math.random().toString().slice(2)
    16. // 2.默认 callback 为 cbFnName
    17. scriptEl.src = `${url}?${stringify({ callback: cbFnName, ...params })}`
    18. // 3.使用 onData 作为回调函数,接收服务端响应数据
    19. window[cbFnName] = onData
    20. document.body.appendChild(scriptEl)
    21. }
    1. const http = require('http');
    2. const url = require('url');
    3. const qs = require('querystring')
    4. const server = http.createServer((req, res) => {
    5. const {pathname, query} = url.parse(req.url)
    6. const params = qs.parse(query)
    7. console.info('params', params)
    8. const data = {msg: params.msg, id: params.id}
    9. if(params.callback) {
    10. const str = `${params.callback}(${JSON.stringify(data)})`
    11. res.end(str)
    12. } else {
    13. res.end()
    14. }
    15. })
    16. server.listen(10010, () => console.info('server.....'))