XmlHttpRequest使用及“跨域”問題解決


一. IE7以后對xmlHttpRequest 對象的創建在不同瀏覽器上是兼容的。

     下面的方法是考慮兼容性的,實際項目中一般使用Jquery的ajax請求,可以不考慮兼容性問題

function getHttpObject() {
var xhr=false;
if (windows.XMLHttpRequest)
    xhr=new XMLHttpRequest();
else if (window.ActiveXObject)
{
    xhr=new ActiveXObject("Microsoft.XMLHttp");
}
return xhr;
}
 

 

 

二. XMLHttpRequest的屬性及方法

1、方法 描述
abort() 停止當前請求
getAllResponseHeaders() 把HTTP請求的所有響應首部作為鍵/值對返回
getResponseHeader(“header”) 返回指定鍵的首部串值
open(“method”,”url”) 建立對服務器的調用,Method可以是GET,POST或PUT,URL可以是相對或絕對URL
send(content) 向服務器發送請求
setRequestHeader(“header”,”value”) 把指定首部設置為所提供的值。在設置任何首部之前必須調用open()


2、屬性 描述
onreadystatechange 每個狀態改變都會觸發,通常會調用一個javascript函數
readyState 請求的狀態,5個值; 0:為初始化,1:正在加載;2:已經加載,3:交互中,4:完成
responseText 服務器的響應,表示為字符串
responseXML 服務器的響應,表示為XML,可以解析為DOM對象
status 服務器的HTTP狀態碼(200:ok,304:not modified,404:Not Found 等)
statusText Http狀態碼的相應文本(ok或Not Found)

 

3、手寫一個Ajax請求的例子:

  eg1: get
$(function(){
      $("#id").onclick(tunction(){
          var request=new XMLHttpRequest();
          var url="http://www.baidu.com";
          var method="GET";    
          request.open(method,url);
          request.send(null);
          request.onreadystatechange=function(){
             if (request.readyState==4&&(request.status==200 || request.status==304))
                alert (request.reponseText);
                //如果返回的是html 標簽,則可以使用 
          //$(“#id2”).innerHtml=request.reponseText;
                //如果返回的xml格式,則需要將結果通過getElementByTagName(“”)[index]解析
         //alert(request.reponseXML.getElementByTagName(“”)[index])
 
          /*var type=request.getResponseHeader("Content-Type");
                if(type.indexOf("xml") !== -1 && request.responseXML){ 
                    callback(request.responseXML); //Document對象響應
                }else if(type=== 'application/json'){
                    callback(JSON.parse(request.responseText)) //JSON響應
                }else {
                    callback(request.responseText);
                }*/
} }) })
 
  eg2: post
<script type="text/javascript">
    var xhr = new XMLHttpRequest();
    xhr.timeout = 3000;
    xhr.ontimeout = function (event) {
        alert("請求超時!");
    }
    var formData = new FormData();
    formData.append('tel', '18217767969');
    formData.append('psw', '111111');
    xhr.open('POST', 'http://www.test.com:8000/login');
    xhr.send(formData);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert(xhr.responseText);
        }
        else {
            alert(xhr.statusText);
        }
    }
</script>

eg3:同步響應
    //同步響應
    //發起同步的HTTP GET請求以獲得指定URL的內容
    //返回響應文本,或如果請求不成功或響應不是文本就報錯。
    function getTextSync(url){
        var request=new XMLHttpRequest();
        request.open("GET",url,false); //把fasle作為第三個參數傳遞給open(),那么send()方法將阻塞直到請求完成
        request.send(null);

        if(request.status!==200) throw new Error(request.statusText);

        var type=request.getResponseHeader('Content-Type');
        if(!type.match(/^text/)) throw new Error("Expected textual respomse;got:"+type);

        return request.responseText;
    }

 

三、.跨域資源共享(CORS)

XMLHttpRequest可以向不同域名的服務器發出HTTP請求,叫做CORS

解決方案:

1)、服務器允許跨域:響應頭需要添加一下選項

     CORS頭缺少“Access-Control-Allow-Origin”, 這個錯誤代表: 服務端拒絕跨域訪問。如果出現這個錯誤,就需要在服務端設置允許跨域請求

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");

    // * 表示允許任何域名跨域訪問
    response.setHeader("Access-Control-Allow-Origin", "*");
    // 指定特定域名可以訪問
    response.setHeader("Access-Control-Allow-Origin", "http:localhost:8080/");

    //數據
    List<Student> studentList = getStudentList();

    JSONArray jsonArray = JSONArray.fromObject(studentList);
    String result = jsonArray.toString();

    //前端傳過來的回調函數名稱
    String callback = request.getParameter("callback");
    //用回調函數名稱包裹返回數據,這樣,返回數據就作為回調函數的參數傳回去了
    result = callback + "(" + result + ")";

    response.getWriter().write(result);
}

  

2)、JSONP,jsonp有缺點,只能發送get請求

下面的方法是考慮兼容性的,實際項目中一般使用Jquery的ajax請求,可以不考慮兼容性問題。

eg1:如何使用<script src="">來完成一個跨域請求
前台:

<%@ page pageEncoding="utf-8" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>跨域測試</title>
<script src="js/jquery-1.7.2.js"></script>
<script>
//回調函數
function showData (result) {
var data = JSON.stringify(result); //json對象轉成字符串
$("#text").val(data);
}

$(document).ready(function () {

$("#btn").click(function () {
//向頭部輸入一個腳本,該腳本發起一個跨域請求
$("head").append("<script src='http://localhost:9090/student?callback=showData'><\/script>");
});

});
</script>
</head>
<body>
<input id="btn" type="button" value="跨域獲取數據" />
<textarea id="text" style="width: 400px; height: 100px;"></textarea>

</body>
</html>

 
后台:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");

//數據
List<Student> studentList = getStudentList();


JSONArray jsonArray = JSONArray.fromObject(studentList);
String result = jsonArray.toString();

//前端傳過來的回調函數名稱
String callback = request.getParameter("callback");
//用回調函數名稱包裹返回數據,這樣,返回數據就作為回調函數的參數傳回去了
result = callback + "(" + result + ")";

response.getWriter().write(result);
}

 

 

eg2:jquery的jsonp方式跨域請求

---后台代碼還是上面的

<%@ page pageEncoding="utf-8" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>跨域測試</title>
<script src="js/jquery-1.7.2.js"></script>
<script>

$(document).ready(function () {

$("#btn").click(function () {

$.ajax({
url: "http://localhost:9090/student",
type: "GET",
dataType: "jsonp", //指定服務器返回的數據類型
success: function (data) {
var result = JSON.stringify(data); //json對象轉成字符串
$("#text").val(result);
}
});

});

});
</script>
</head>
<body>
<input id="btn" type="button" value="跨域獲取數據" />
<textarea id="text" style="width: 400px; height: 100px;"></textarea>

</body>
</html>

 3)、搭建網關系統

 

附其他:

這里再插入一下window.onload 和$(function(){})($(document).ready(function(){}))的區別:

1. window.onload 必須等到頁面內包括圖片的所有元素加載完畢才能執行

    $(function(){}) 是DOM結構繪制完畢后就執行,不必等到加載完畢

2. 編寫個數不同

    window.onload 不能同時編寫多個,如果有多個window.onload方法,只會執行一個

    $(function(){}) 可以同時編寫多個,並且都會得到執行

3. 簡化寫法

    window.onload 沒有簡寫方法,但可以使用$(window).load(function(){})代替

    $(function(){})實際是$(document).ready(function(){})的縮寫方法

    $(window).load(function(){}),IE只有在不是frame的情況下,一般情況下都會在$(function(){})之后執行.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM