[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)
最终可以得到页面结果
页面也无任何跨域报错
本想把生活活成一首诗, 时而优雅 , 时而豪放 , 结果活成了一首歌 , 时而不靠谱 , 时而不着调