[javascript] 关于jsonp跨域的二三事

出于浏览器同源政策的影响, 如果服务器不允许跨域, 客户端与服务器不同源, 请求就会失败, 提示如下

但是有些标签是例外的, 比如说图片的url, script标签的 url

而作为web脚本语言的javascript, 本质上其实是字符串

不信你可以在script内部  console.log("</script>") 试试, 这个打印会被默认成script的结束

而script请求到的内容填充到浏览器script标签后, 会立即执行里面的内容, jsonp就是利用这个机制, 让服务端返回一个函数的调用, 实现浏览器对获取的数据的处理

 

web代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta
    name="viewport"
    content="width=device-width, initial-scale=1.0"
  >
  <title>测试</title>
</head>

<body>
  <button>获取数据</button>
  <ul>

  </ul>


  <script>
    const btn = document.querySelector('button')
    const ul = document.querySelector('ul')

    function render_data(data) {
      console.log(data)
      const lis = []
      data.forEach(d => {
        const li = document.createElement('li')
        li.textContent = d.name
        lis.push(li)
      })
      ul.innerHTML = ''
      ul.append(...lis)
      del_script('req1')
    }

    function del_script(id) {
      const script = document.querySelector(`script[data-id=${id}]`)
      script.remove()
    }


    btn.addEventListener('click', () => {
      const url = 'http://127.0.0.1:5000/get_data?cb=render_data'
      const script = document.createElement('script')
      script.setAttribute('src', url)
      script.setAttribute('data-id', 'req1')
      document.body.appendChild(script)
    })

  </script>

</body>

</html>

代码解析

点击按钮动态生成并插入script, 传入回调函数

服务器收到之后, 直接返回一个函数的调用, 参数为服务器查询到的数据(此处为模拟数据)

客户端渲染script结果后, 立即执行函数, 页面就能看到内容了

 

服务器代码 语言python

from flask import Flask, request

app = Flask(__name__)


@app.route('/get_data', methods=["GET"])
def get_data():
    cb = request.args.get('cb')
    lis = [
        {"id": 1, "name": "张三"},
        {"id": 2, "name": "李四"},
        {"id": 3, "name": "王五"},
        {"id": 4, "name": "赵六"},
        {"id": 5, "name": "小七"},
    ]
    return f'{cb}({lis})'


if __name__ == '__main__':
    app.run(debug=True)

 

最终可以得到页面结果

页面也无任何跨域报错

posted @ 2024-10-16 10:44  深海里的星星i  阅读(5)  评论(0编辑  收藏  举报