在完成上次简单的测试之后,接下来将结合《javascript权威指南》关于jsonP例子,介绍如何动态请求和响应数据. 首先,我们需要编写一个客户端页面,通过绑定事件的方式,向指定地址发送jsonP请求。
服务端1: Node . URL : http://localhost:3000
服务端2: Nginx+PHP . URL : http://localhost:8080
同一主机,不同端口符合同源策略。
首先我们现在设置服务端2的页面,主要是产生一个可视化文档,填写参数向目的地发送请求。
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonP</title>
<script>
var getJSONP = { counter : 0}; // 管理jsonP请求次数 和 函数
function sendRequest(){
var q = document.getElementsByName("qname")[0].value; //取得 文本框数据
var url = "http://localhost:3000"; //设置为 node 服务端 地址
if(typeof q !="undefined"){
url+="?q="+q; //附加参数
}
createJsonP(url,function(res){ //开始执行jsonP函数
console.log(res);
});
}
function createJsonP(url,callback){ // 发送请求 url 和 回调函数
console.log("start");
var cbnum = "cb" + getJSONP.counter++ ; // 每一次jsonP请求 都会进行统计 自增
var cbname = "getJSONP." +cbnum; // callback 回调函数唯一名称
if(url.indexOf("?")==-1){
url+="?jsonp=" + cbname; //这里的jsonp 键名是一个关键字,将与服务端1获取get请求参数名一致。而键值则是请求成功后调用的函数名称
}else{
url+="&jsonp=" + cbname;
}
var script = document.createElement("script"); // 创建一个script 元素
// 预先设置好 回调函数
getJSONP[cbnum] = function (res){ //设置script 元素的 src 之前 声明好 回调函数.
try{
console.log(getJSONP);
callback(res); // 执行真正的 回调函数.
}finally{
// 执行完回调函数后 删除辅助的回调函数 和 刚刚添加的script元素
delete getJSONP[cbnum];
script.parentNode.removeChild(script);
}
};
// 设置 请求地址 此时才开始进行ajax请求 脚本
script.src = url;
document.documentElement.appendChild(script); //添加到 文档里面
}
</script>
</head>
<body>
<label for="">qname:</label>
<input type="text" id ="val" name="qname">
<button id="btn">开始请求</button>
</body>
<script>
window.onload = function (){
var btn = document.getElementById('btn');
btn.addEventListener("click",sendRequest,false);
}
</script>
</html>
接下来是Node环境里处理该请求,实际上使用任何服务端脚本语言都可以,只要将返回的格式为 callbak( json格式参数 ), 客户端脚本就会执行 callback方法。
var express = require('express');
// 建立 express 实例
var app = express();
app.get('/', function (req, res) { // 监听根目录
var data = { name:"abc",type:"jsonP" , q : req.query.q };
var str = req.query.jsonp + '(' + JSON.stringify(data) + ')';//jsonp 是一个关键名 req.query.jsonp 就是获取客户端传递过来的 get请求中的jsonp键值
if(typeof req.query.q !="undefined"){
console.log("request q is "+str);
}
res.send(str); //返回符合格式的字符串
});
app.listen(3000, function (req, res) {
console.log('app is running at port 3000');
});
接下啦.我们进行一次测验.首先查看客户端页面
我们在文本框填写数据后,点击按钮.进行发送.这是会发送一个如下的get请求
可以看到getJSONP.cb0是我们第一次的回调函数名称. 而getJSONP 对象的格式如下:
产生立一个cb0的属性,属性类型为函数类型.
服务端1 在终端输出的内容为:
说明确实有请求进行访问.同时返回的格式为: getJSONOP.cb0({}); 这样 当客户端请求成功后 , 会执行getJSONP 对象里的cb0函数。执行的结果就是调用真正的callback函数,将数据传递给callback函数.同时销毁 getJSONP 对象的 cb0函数,
真正的callback函数 就会将我们的json 数据打印在客户端控制台中。
这样,一个动态的设置参数请求jsonP的例子就介绍完了。实际上本身就是利用了script 元素可以引用外部任何javascript格式的脚本. 支持跨域,跨服务器.避免了同源策略的产生.
关于如何避免同源策略的问题,我们还得需要通过更多的例子进行介绍.