JSONP概述:
请求方:hua.com的前端程序员(浏览器)
响应方:zhen.com的后端程序员(服务器)
1.请求方创建script,src指向响应方,同时传一个查询参数 ?callbackName=xxx
2.响应方根据查询参数callbackName,构造形如
1.xxx.call(undefined, '你要的数据')
2.xxx('你要的数据')
这样的响应
3.浏览器接收到响应,就会执行,xxx.call(undefined,'你要的数据')
4.那么请求方就知道了他要的数据
这就是JSONP
约定:
callbackName ---(一定叫做)---> callback / jQuery_callback(jQuery中用)
yyy --------(一般用随机数)---------> 随便取名字,用完就不要了啊。
1.我们跨域访问一个服务器下的文件:
启动本地服务器,根目录下有remote.js文件
alert('服务器文件')
本地有一个jsonp.html文件
在这里,很直接的就可以弹出提示框
2.我们在jsonp.html页面定义一个函数,然后在远程remote.js中传入数据进行调用
//放在head中
var xxx = function(data) {
alert('这是一个本地函数,可以被跨域的remote.js文件调用,远程带来的数据是:' + data.result)
}
alert('服务器文件')
xxx({ 'result': '这是服务器带来的数据~~~' })
运行后发现,页面弹出提示框,“服务器文件”,并且显示本地定义的xxx函数被远程js调用成功,而且接受了远程js带来的数据。
那么,接下来,我们只需要让这个过程动态创建就可以了~
3.动态创建,做一些大的改动
我们现在已经知道,我们可以使用标签,从本地访问服务器的资源,并且可以拿到服务器中的东西。
现在我们做一些改动,将remote.js设置为我们的http服务器:
1.简单处理下url
2.访问一个JSON文件,给客户端返回其中的数据
rmeote.js
var http = require('http');
var url = require("url");
var fs = require('fs')
var queryString = require("querystring");
http.createServer(function(request, response) {
var parseUrl = url.parse(request.url)
var path = parseUrl.pathname
query = queryString.parse(parseUrl.query)
if (path === '/remote.js') {
let jsonObject = fs.readFileSync('./person.json').toString()
response.setHeader('content-type', 'text/javascript')
response.statusCode = 200
response.write(`${query.callback}.call(undefined,${jsonObject})`)
response.end()
}
}).listen(8888);
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
person.json
{
"person": [
{ "firstname": "liu", "lastname": "bei" },
{ "firstname": "zhang", "lastname": "fei" },
{ "firstname": "guan", "lastname": "yu" }
]
}
接下来,我们就需要设置 jsonp.html,动态的创建标签,访问服务器,并且拿到服务器中的数组
jsonp点击发起跨域请求
xxx = function(data) {
alert('这是一个本地函数,可以被跨域的remote.js文件调用,远程带来的数据是:' + '第一个人的名字是' + data.person[0].firstname + ' ' + data.person[0].lastname)
}
button.addEventListener('click', () => {
var script = document.createElement('script')
script.src = 'http://127.0.0.1:8888/remote.js?callback=xxx'
document.body.appendChild(script)
//成功后删除标签
script.onload = function(e) {
e.currentTarget.remove()
}
})
最后会弹出对话框,正确显示liu bei这个名字。也就是说,我们通过浏览器,访问服务器,服务器确实给我们提供了person.json中的数据。
4.最后,我们按照约定,将代码做一个优化:
代码见:
附:
substring() 方法返回一个字符串在开始索引到结束索引之间的一个子集, 或从开始索引直到字符串的末尾的一个子集。
delete 操作符用于删除对象的某个属性;如果没有指向这个属性的引用,那它最终会被释放。