XMLHttpRequest的同域请求和跨域请求以及jsonp

XMLHttpRequest的同域请求和跨域请求以及jsonp

  • XMLHttpRequest的同域请求和跨域请求以及jsonp
  • 使用XMLHttpRequest
  • xhr同域请求
      • get
      • post
  • xhr跨域请求
  • jsonp

使用XMLHttpRequest

先创建一个xhr对象,下面代码是js高级程序设计里面给出的兼容性代码

function createXHR() {
        if(typeof XMLHttpRequest != "undefined"){
            return new XMLHttpRequest();
        }else if(typeof ActiveXObject != "undefined"){
            if(typeof arguments.callee.activeXString != "string"){
                var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"];

                for(var i=0, len=versions.length;i < len; i++){
                    try{
                        var xhr = new ActiveXObject(versions[i]);
                        arguments.callee.activeXString = versions[i];
                        return xhr;
                    }catch(ex){
                            //跳过
                    }
                }
            }
            return new ActiveXObject(arguments.callee.activeXString);
        }else{
            throw new Error("NO XHR object available");
        }
}
var xhr = createXHR();

xhr同域请求

同域请求下,服务端不需要做多余的配置即可使用
统一使用php作为服务端,返回下列信息

if(isset($_POST['id']) && !empty($_POST['id'])){
    echo json_encode(array("code" => 1, "msg" => "success", "id" => $_POST['id']));
    //{"code":1,"msg":"success","id":1}
}else if(isset($_GET['id']) && !empty($_GET['id'])){
    echo json_encode(array("code" => 1,"msg" => "success", "id" => $_GET['id']));
    //{"code":1,"msg":"success","id":1}
}else{
    echo json_encode(array("code" => 0,"msg" => "fail"));
    //{"code":1,"msg":"fail"}
}

get

get方法的客户端

xhr.onreadystatechange = function () {
    if(xhr.readyState === 4){
        if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
            alert(xhr.responseText);
        }else{
            alert("Response wa unsuccessful: " + xhr.status);
        }
    }
};
xhr.open('GET', "./jsonp.php?id=1", true); //异步请求
xhr.send(null); //有些浏览器是必须填null

post

xhr.onreadystatechange = function () {
    if(xhr.readyState === 4){
        if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
            alert(xhr.responseText);
        }else{
            alert("Response wa unsuccessful: " + xhr.status);
        }
    }
};
xhr.open('POST', "./jsonp.php", true); //异步请求
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");//post请求增加的
xhr.send("id=1");

xhr跨域请求

跨域请求即请求不同在一个域名上的请求,这里我开启了两个apache服务器端口来测试,xhr请求文件放在localhost:8008上面,php服务端放在localhost:80上面
xhr跨域请求主要是多了一个origin的header,而这部分主要在php服务端上进行设置就好,客户端的js脚本其实和同域请求并无太大区别
其中第一个是必选的

header('Access-Control-Allow-Origin:http://localhost:8008');//设置允许访问的域
header('Access-Control-Allow-Credentials: true');//设置是否发送cookie,需要在客户端同时设置才会生效
header('Access-Control-Allow-Headers:X-Requested-With');//允许的访问头部,也需要在客户端同时设置,同时为了避免跨域访问出错,客户端最好不要设置该项信息,避免服务端不允许
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE');//支持的请求方式

客户端
这里网上说了有简单跨域和复杂跨域,区别主要在请求方式和参数设置上,我就不说了,主要是我也还没理解透,可以看看利用CORS实现跨域请求

//直接是post请求
var url = "http://localhost/jsonp.php"; //我们这里的客户端代码运行在localhost:8008
xhr.open('POST', url, true);
xhr.withCredentials = true; //设置传递cookie,如果不需要直接注释就好
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); //请求头部,需要服务端同时设置
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("id=1");

以上就是cors跨域的小小实例,可以看出cors跨域支持多种请求方式

jsonp

jsonp应该是第一代的跨域请求解决方案了,它的解决思路是利用script标签上的src属性不受跨域影响的特性解决了,就像img标签也不受跨域影响,然后script会请求一个服务端程序,服务端程序可以是任意语言,需要的只是返回一个使用js回调函数的字符串即可
由于客户端的回调函数名是在客户端定义的,所以服务端就必须返回与客户端的回调函数一致的函数名,为了实现动态加载的目的
php这样写

 $callback = $_GET['callback'];
 $code = $_GET['code'];
 echo $callback."({'code':'".$code."','price':1780,'tickets':5})";
 //回调函数名({'code':'传递的参数','price':1780,'tickets':5})

客户端js

// 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://localhost/jsonp.php?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script);

使用jquery实现jsonp

$.ajax({
    type: "get",
    url: "http://localhost/jsonp.php?code=CA1998",
    dataType: "jsonp",
    jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
    jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
    success: function(json){
        alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
    },
    error: function(){
        alert('fail');
    }
});

可以看到jsonp的实现方式其实很简单,但它的功能有一定的限制,配置项也没有cors的丰富,最重要的是jsonp只能发送GET请求,而cors可以发送GET或POST以及其他的请求

你可能感兴趣的:(javascript)