Ajax和跨域

1.使用:

ie是第一款引入XHR对象的浏览器,ie7+只要一句,var xhr=new XMLHttpRequest();就可以了。

1、创建异步对象

// 进行createXMLHttpRequest对象的创建,由于不同的XMLHttpRequest的支持不同所以根据不同的浏览器创建
function createXMLHttpRequest(){
    //对遵守DOM2规范的浏览器
    if(window.XMLHttpRequest){
        objXMLHttp = new XMLHttpRequest();
    }
    else{
        //ie 太多了循环下
        var IEXML = ['MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'];
        for(var i=0; i < IEXML.length ; i++){
            try{
                //微软发布的Active控件
                objXMLHttp = new ActiveXObject(MSXML[i]);break;
            }catch(e){
                alert("创建xmlhttprequesst对象失败!");
            }
        }
    }
}
var xhr=createXMLHttpRequest();//字面量模式会立即执行

2提交

get提交:

xhr.open("GET", "Ajax.ashx?id=" + id, true);
objXMLHttp.send(null);

post提交:

为了使得服务器像表单那样去处理,采用模拟Content-Type头的方式:

xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

 发送

xhr.send(ser);

可以将ser序列化之后在发送给服务器,序列化的方法:

JSON.stringify(js对象);//将js对象转化为json字符串

JSON.parse();//与上面相反

处理

定义回调函数与异步监听

xhr.onreadystatechange = function() {
     if (xhr.readyState == 4) {

           if (xhr.status == 200) { ///判断服务器返回的状态码是否为200,如果不是,则可能服务器出现了不测
           var res = xhr.responseText;//接收返回的效果
           

            }
        }
}

load事件:IE8+和其他都支持,接收到完整数据时触发

process事件:用于监听接收数据的进度

完整的

var objXMLHttp;
//进行createXMLHttpRequest对象的创建,由于不同的XMLHttpRequest的支持不同所以根据不同的浏览器创建
function createXMLHttpRequest(){
    //对遵守DOM2规范的浏览器
    if(window.XMLHttpRequest){
        objXMLHttp = new XMLHttpRequest();
    }
    else{
        //ie 太多了循环下
        var IEXML = ['MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'];
        for(var i=0; i < IEXML.length ; i++){
            try{
                //微软发布的Active控件
                objXMLHttp = new ActiveXObject(MSXML[i]);break;
            }catch(e){
                alert("创建xmlhttprequesst对象失败!");
            }
        }
    }
}
//通过POST方式提交
function postSend(){
    //获取contentvalue
    var contentvalue =  document.getElementById("content").value;
    alert(contentvalue);
    //初始化xmlhttprequest对象
    createXMLHttpRequest();
    //创建url
    var url =  "ajaxServlet";
    //打开与服务器的连接 用post
    objXMLHttp.open("POST", url, true);
    //post需要设置消息头
    objXMLHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    //回调函数
    objXMLHttp.onreadystatechange = processResponse;
    //发送设置的参数,形式: param = value
    objXMLHttp.send("value="+contentvalue);
}
//通过get方式请求
function getSend(){
    //获取value
    var contentvalue = document.getElementById("content").value;
    alert("get:"+contentvalue);
    //初始化xmlhttprequest对象
    createXMLHttpRequest();
    //创建url,get方式采用url拼接传参数
    var url =  "ajaxServlet?value="+contentvalue;
    //打开与服务器的连接 用post
    objXMLHttp.open("GET", url, true);
    //回调函数
    objXMLHttp.onreadystatechange = processResponse;
    //发送设置的参数,参数已经上面传
    objXMLHttp.send(null);
}

function processResponse(){
    if(objXMLHttp.readySatae== 1){
        alert("XMLHttpRequest对象开始发送");
    }else if(objXMLHttp.readySatae== 2){
        alert("XMLHttpRequest对象发送完成");
    }else if(objXMLHttp.readySatae== 3){
        alert("XMLHttpRequest对象读取服务器响应开始");
    }else if(objXMLHttp.readySatae== 4){
        alert("XMLHttpRequest对象读取服务器响应结束");
        if(onjXMLHttp.status == 200){
            //信息已经成功返回,处理开始
            var headers = objXMLHttp.getAllResponseHeaders();
            aler(headers);
            //得到服务器返回的信息
            var infor = objXMLHttp.responseText;
            alert(infor);
        }else{
            alert("请求的服务器问题");
        }
    }
}
View Code

jquery中ajax

jquery提供了$.ajax,$.get(),$.post()等方法

$.ajax({
                url: "/CommonService.asmx/SayHello",
                type: "Post",
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                data: "{name:'Varchar32'}",
                success: function (data) {
                    alert(data.d);
                },
                error: function (data) {
                    //200的响应也有可能被认定为error,responseText中没有Message部分
                    alert($.parseJSON(data.responseText).Message);
                },
                complete: function (data) {
                    ;//after success or error
                }
 });

 到这里还要特别介绍一个插件:jQuery.form插件,官网:http://malsup.com/jquery/form/它在jquery调用webservice中很好使用

使用:http://www.cnblogs.com/heyuquan/p/form-plug-async-submit.htmlhttp://www.cnblogs.com/fish-li/archive/2013/01/13/2858599.html#_label3

它的ajaxForm直接提交整个表单,而且还能根据name标示来选择不同的方法提交,提交各种复杂表单。

名词解释

CSRF(Cross-Site Request Forgery,跨站点请求伪造)

CORS(Cross-Origin Resource Sharing ,跨域资源共享)

 SSE(Server-Sent Events,服务器发送事件)

跨域

原因:同源策略(XHR对象只能访问包含它的页面位于同一个域中的资源,协议域名端口相同)

方法:

1.服务器段设置

Access-Control-Allow-Origin:* 代表所有域名都可以访问到
Access-Control-Allow-Origin: http://www.cnblogs.com 限定了域名

2.图像ping

使用<img>标签,这种技术在大访问量的页面上可以将图片设为其他服务器上,降低服务器压力

3.JSONP

利用<script>可以作为一种很好的跨域方案。

var script=document.createElement("script");

script.src="http://dfsa.net/json/?callback=responsejs";

document.body.insertBefore(script,document.body.firstChild);

必须指定回调函数这里指定responsejs

服务器端则必须返回一段js脚本,如json对象数组定义的脚本

modlist = [
{“modname” : “mod1”,  “usernum” : 200, “url” : ” /widget/info/1”},
{“modname” : ”mod2”,  “usernum” : 300, ”url” : ” /widget/info/2”},
…
];

然后判断这个脚本加载完毕(可以利用这个调用百度搜索:Script.src = 'http://suggestion.baidu.com/su?wd='+oTxt.value+'&p=3&cb=baidu&from=superpage')

js.onload = js.onreadystatechange = function() {
    if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
        // callback在此处执行
        js.onload = js.onreadystatechange = null;
    }
};

4.iframe+document.domain方式

  对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。具体的做法是可以在http://www.a.com/a.html和http://script.a.com/b.html两个文件中分别加上document.domain = ‘a.com’;然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以“交互”了。当然这种办法只能解决主域相同而二级域名不同的情况,如果你异想天开的把script.a.com的domian设为alibaba.com那显然是会报错地!代码如下:

www.a.com上的a.html

document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.a.com/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
    var doc = ifr.contentDocument || ifr.contentWindow.document;
    // 在这里操纵b.html
    alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};

script.a.com上的b.html

document.domain = 'a.com';

5.jquery中封装的$.get(),和$.ajax()的get模式可以跨域,还有$.getJSON()方法

 $.getJSON("http://localhost:12500/CommonService.asmx/GetGenderByName?name=Varchar32&callback=?",
             function (data) {
                 alert("in success" + ":" + data.name + ", 性别" + data.gender);
            }
        ); 

服务器推送:Comet

1长轮询:页面js轮询服务器,实例:

   window.setInterval(function () {
                
                    $.get("${pageContext.request.contextPath}/communication/user/ajax.mvc", 
                        {"timed": new Date().getTime()}, 
                        function (data) {
                            $("#logs").append("[data: " + data + " ]<br/>");
                    });
                }, 3000);

2。SSE是围绕只读Comet推出的API,只在简化HTTP流和长轮询代表的Comet的技术的使用

3. Web Sockets 使用了全新的Web Socket协议。一些聊天室使用这个。

原文地址:https://www.cnblogs.com/wanglao/p/3558049.html