- 前言
jsonp并没有解决跨域, 而是绕过跨域去达成目的, 解决跨域的方法只有一种: 后端设置cors - 基础模式
前端请求接口, 告诉后端函数名(函数要先在前端定义)
html
<script>
function getUserInfo(obj) {
console.log(obj);
}
</script>
<script src="http://127.0.0.1:3005/jsonp.js?fn=getUserInfo"></script>
- jsonp封装
通过动态创建script标签, 给window挂一个全局函数, 然后在该函数的回调中取到后端数据
html
<script>
function jsonp(url, queryData, success) {
let fn = 'fn' + Date.now();
let queryStr = Object.entries(queryData)
.map(([key, val]) => {
return key + '=' + val;
})
.join('&');
const scriptEl = document.createElement('script');
scriptEl.src = url + '?' + queryStr + '&fn=' + fn;
const headEl = document.querySelector('head');
headEl.appendChild(scriptEl);
window[fn] = data => {
success(data);
delete window[fn];
headEl.removeChild(scriptEl);
};
}
</script>
<script>
function getUserInfo(obj) {
console.log(obj);
}
jsonp(
'http://127.0.0.1:3005/jsonp.js',
{
user: 'jian'
},
getUserInfo
);
</script>
- node后端部分(后端解决跨域的部分可省略)
js
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
const server = http.createServer((req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE');
if (req.method === 'OPTIONS') {
res.writeHead(200);
res.end();
} else if (/^\/jsonp.*/.test(req.url)) {
let { query } = url.parse(req.url, true);
res.writeHead(200, { 'Content-Type': 'text/plain' });
let result = JSON.stringify({ id: 1, name: '张三' });
setTimeout(() => {
res.end(`${query.fn}(${result})`);
}, 2000);
}
});
server.listen(3005);
jsonp解决跨域问题, 到现在已经是古老的洪水猛兽, 就像声明变量关键字var一样