跨域问题对于前端来说已经属于老生常谈的问题了,而jsonp就是我们处理跨域方案的一种,但是因为它只支持get请求,所以有很大的局限性,但是其原理平常面试的过程中多数都会问到,故此通过一个node服务器来详细解释一下其原理。
1、创建http服务器
http模块是node.js中内置的一个模块,我们通过调用它的createServer
方法就可以创建一个简单的服务器。Access-Control-Allow-Origin
可以设置允许访问的web服务器,其值设为*表示允许所有的服务器访问。
// 引入模块
const http = require('http');
let data = {
name: '小明',
sex: '男',
age: 16
};
// 创建http服务器
http.createServer(function (req, res) {
// 设置请求头
res.writeHead(200, {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'text/plain;charset=UTF-8'
});
res.end(JSON.stringify(data))
}).listen(8080);
2、发起ajax请求
使用原生的XMLHttpRequest
对象发起一个ajax请求,请求结果如下图:
const xhr = new XMLHttpRequest();
xhr.open('get', 'http://localhost:8080', true);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.response))
}
};
xhr.send(null);
3、跨域请求
jsonp就是利用script标签的src属性不受浏览器同源策略限制,我们将请求地址设为src属性值并在其中拼接一个callback参数,callback的值为一个回调函数的函数名应提前与后端约定好(比如下面的示例callback的值为getData),然后由后端返回该函数的调用,并将对应数据设为该回调函数的参数,前端通过调用这个回调函数,取得其中传入的参数,即可拿到后端传回来的数据,具体示例如下:
- 创建node服务器
const http = require('http');
const url = require('url');
let data = {
name: '小明',
sex: '男',
age: 16
};
http.createServer(function (req, res) {
const params = url.parse(req.url, true);
if(params && params.query.callback) {
// jsonp请求
// 获取请求参数中callback的值,并返回一个函数调用的字符串
const str = params.query.callback+`(${JSON.stringify(data)})`;
res.end(str)
} else {
// 普通ajax请求
res.end('helloWorld')
}
}).listen(8080)
- 封装jsonp并发起请求
function getData(data) {
console.log(data)
}
createJsonp('http://localhost:8080/?callback=getData');
function createJsonp(url) {
const script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
}