【javascript】 借助script元素发送HTTP请求:JSONP原理-2

来源:互联网 发布:bt下载软件 编辑:程序博客网 时间:2024/06/06 02:22

   在完成上次简单的测试之后,接下来将结合《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格式的脚本. 支持跨域,跨服务器.避免了同源策略的产生.

  关于如何避免同源策略的问题,我们还得需要通过更多的例子进行介绍.


0 0
原创粉丝点击