JavaScript之跨域请求解决方案

浏览器处于安全原因,在使用 Ajax 进行请求访问时,不允许跨域请求。
因为这涉及到(被浏览器添加在每次请求的请求头中的)Cookie 会被外域服务器读取到。

不过我们发现,Web页面上使用 script 标签加载js文件时则不受是否跨域的影响。也就是可以加载其它域名下的 javascript 文件。(不仅如此,我们还发现凡是拥有"src"这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>);
基于此,实现跨域请求,只需要动态加载 js 文件就可以了。
但是动态加载 js 后,应该调用那个方法处理这些数据。我们只好把这个回调方法的名称以参数的形式传递给服务器。

这就是JSONP的实现原理:

1、动态的向页面中添加 src 属性为其它域名资源的 script 标签。
2、把回调方法写到 src 参数里,一起传递给服务器。
3、服务器在返回的 javascript 文件中,调用这个回调方法。


一、实现原理

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript">

    // callback function.
    var flightHandler = function(data){
        console.log(data);
    };
    
    // 该 url 会返回一段 javascript 代码。
    var url = "http://remote.xx.com/xx?code=CA1998&callback=flightHandler";

    // 创建script标签
    var script = document.createElement('script');
    script.setAttribute('src', url);

    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>

</body>
</html>


服务器端端返回值:
var obj = {
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
};

flightHandler(obj);


为了不引起 obj 变量名冲突,写成 JSONP (JSON with Padding) 格式:
flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});





二、使用 JQuery 时,它把这种方式封装在了 ajax 方法中
但这绝不是 ajax 请求,实现原理不同。
$.ajax({
     type: "get",
     async: false,
     url: "http://remote.xx.com/xx?code=CA1998",
     dataType: "jsonp",
     jsonp: "callback",
     jsonpCallback:"flightHandler",
     success: function(data){
         console.log(data);
     },
     error: function(){
         alert('fail');
     }
 });




$.ajax({
     type: "get",
     async: false,
     url: "http://remote.xx.com/xx?code=CA1998",
     jsonp: "callback",
     jsonpCallback:"?", 
     success: function(data){
         console.log(data);
     },
     error: function(){
         alert('fail');
     }
 });

如果在 url 中含有 callback=? ,则 jquery 会认为是发送 jsonp 格式的请求。
并自动生成一个随机的回调函数名,传递给服务器。



JQuery 自动生成的 callback 方法名是如何调用 sucess 方法的?

$.ajax({
        url: 'http://url.of.my.server/submit',
        dataType: "jsonp",
        jsonp: 'callback',
        jsonpCallback: 'jsonp_callback'
    });

jsonp is the querystring parameter name that is defined to be acceptable by the server while the jsonpCallback is the javascript function name to be executed at the client.
When you use such url:

url: 'http://url.of.my.server/submit?callback=?'

the question mark ? at the end instructs jQuery to generate a random function while the predfined behavior of the autogenerated function will just invoke the callback -the sucess function in this case- passing the json data as a parameter.

$.ajax({
        url: 'http://url.of.my.server/submit?callback=?',
        success: function (data, status) {
            mySurvey.closePopup();
        },
        error: function (xOptions, textStatus) {
            mySurvey.closePopup();
        }
    });


The same goes here if you are using $.getJSON with ? placeholder it will generate a random function while the predfined behavior of the autogenerated function will just invoke the callback:

$.getJSON('http://url.of.my.server/submit?callback=?',function(data){
//process data here
});



引用

jsonpCallback
Type: String or Function()

Specify the callback function name for a JSONP request. This value will be used instead of the random name automatically generated by jQuery. It is preferable to let jQuery generate a unique name as it'll make it easier to manage the requests and provide callbacks and error handling. You may want to specify the callback when you want to enable better browser caching of GET requests. As of jQuery 1.5, you can also use a function for this setting, in which case the value of jsonpCallback is set to the return value of that function.




服务端返回数据的示例代码:
public void ProcessRequest (HttpContext context) {
	context.Response.ContentType = "text/plain";
	String callbackFunName = context.Request["callbackparam"];
	context.Response.Write(callbackFunName + "([ { name:\"John\"}])");
}





引用请注明,
原文出处:http://lixh1986.iteye.com/blog/2378307








-
引用:
http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html
http://api.jquery.com/jQuery.ajax/
https://stackoverflow.com/a/31087311/2893073



猜你喜欢

转载自lixh1986.iteye.com/blog/2378307