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

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

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


发布了31 篇原创文章 · 获赞 6 · 访问量 7万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章