> XMLHttpRequest 是一個 JavaScript 對象,它最初由微軟設計,隨後被 Mozilla、Apple 和 Google採納. 現在,該對象已經被 W3C組織標準化. 經過它,你能夠很容易的取回一個URL上的資源數據. 儘管名字裏有XML, 但 XMLHttpRequest 能夠取回全部類型的數據資源,並不侷限於XML。 並且除了HTTP ,它還支持file 和 ftp 協議. —— MDN XMLHttpRequestjavascript
XMLHttpRequest
讓發送一個HTTP
請求變得很是容易。你只須要簡單的建立一個請求對象實例,打開一個URL
,而後發送這個請求。當傳輸完畢後,結果的HTTP
狀態以及返回的響應內容也能夠從請求對象中獲取。html
第一步:建立一個 XMLHttpRequest 實例html5
new XMLHttpRequest();
第二步:初始化HTTP請求參數java
void open( DOMString method, DOMString url, optional boolean async, optional DOMString user, optional DOMString password );
HTTP
方法; 例如"GET"
,"POST"
,"PUT"
,"DELETE"
等. 若是下個參數是非HTTP(S)
的URL
,則忽略該參數.URL
true
,意味着是否執行異步操做,若是值爲false
,則send()
方法不會返回任何東西,直到接受到了服務器的返回數據。若是爲值爲true
,一個對開發者透明的通知會發送到相關的事件監聽者。這個值必須是true
,若是multipart
屬性是true
,不然將會出現一個意外。string
.string
.第三步:發送請求git
send();
發送請求. 若是該請求是異步模式(默認),該方法會馬上返回. 相反,若是請求是同步模式,則直到請求的響應徹底接受之後,該方法纔會返回.github
以下例:json
var xhr = new XMLHttpRequest(); xhr.onload = function () { console.log(this.responseText); }; xhr.onreadystatechange = function() { console.log(this.readyState); }; xhr.open("get", "https://www.baidu.com", true); xhr.send();
咱們在hbuilder裏面打開,控制檯會報錯:segmentfault
[Web瀏覽器] "XMLHttpRequest cannot load https://www.baidu.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8020' is therefore not allowed access."
用瀏覽器打開,按F12
在控制檯console
下查看也會發現上述錯誤,這是爲啥呢?後端
這是由於普通網頁可以使用XMLHttpRequest
對象發送或者接受服務器數據, 可是它們受限於同源策略。只要先獲取了跨域請求許可,就能夠進行跨域請求。跨域
> 同源策略:若是兩個頁面的協議、域名和端口是徹底相同的,那麼它們就是同源的。同源策略是爲了防止從一個地址加載的文檔或腳本訪問或者設置從另一個地址加載的文檔的屬性。若是兩個頁面的主域名相同,則還能夠經過設置document.domain
屬性將它們認爲是同源的。
第一種:CORS,使用XMLHttpRequest對象
CORS 的全稱是 Cross-Origin Resource Sharing,即跨域資源共享。他的原理就是使用自定義的 HTTP 頭部,讓服務器與瀏覽器進行溝通,主要是經過設置響應頭的 Access-Control-Allow-Origin 來達到目的的。這樣,XMLHttpRequest 就能跨域了。
在服務器端添加響應頭Access-Control-Allow-Origin
,使用XMLHttpRequest
對象請求。值得注意的是,正常狀況下的 XMLHttpRequest 是隻發送一次請求的,可是跨域問題下極可能是會發送兩次的請求(預發送)。
PHP:
header('Access-Control-Allow-Origin: *');
java:
response.addHeader( "Access-Control-Allow-Origin", "*" );
第二種:Jsonp,只適用於get請求
Jsonp
的跨域不是用XMLHttpRequest
實現的,而是一個script
標籤,script
是能夠跨域的,回調函數做爲get
參數傳入請求裏。
原理很簡單,好比你在A域名請求B域名:
- 在A域名的頁面中使用script標籤src寫成B域名中服務器的URL
script標籤是能夠跨域的,好比你調用Google Map或Google Analytics時引入的js就是google域名下的。
- 後端程序在最後須要把一段js代碼的字符串print出來,這樣就能夠運行A域名js中寫好的callback方法,將要返回的數據放入參數就能夠了
A域名中的js文件:
<script type="text/javascript" src="http://www.b.com/action?callback=myCallback"></script> <script type="text/javascript"> function myCallback (data) { alert(data); } </script>
B域名中服務器
String cb = get('callback'); Int b = '我是數據'; print('<script type="text/javascript"> ' + cb + '(' + b + '); </script>');
後端print數據到頁面中後就會這樣
<script type="text/javascript"> myCallback('我是數據'); </script>
> 注:引用自segmentfault 的tychio的回答。
總之,不管是XMLHttpRequest
的跨域,仍是Jsonp
,都是須要請求的網站服務器端提供支持,在願意分享給你數據的狀況下你才能獲得。在對方沒有提供支持的狀況下,你是取不到它的數據的。固然跨域的解決方案有不少種,因爲本人沒有實踐過,沒有實踐就沒有發言權,這裏給你們貼一個帖子,本身跨域自行驗證,淺談瀏覽器端JavaScript跨域解決方法。
上面咱們花了很大篇幅講解了JavaScript XMLHttpRequest
對象,並且也簡單的講解了同源策略和跨域請求的經常使用方法,咱們注意到不管是JavaScript XMLHttpRequest
仍是jsonp
都須要經過服務器端的支持才能實現跨域,另外還有幾種也有必定的侷限性,因此總仍是讓人以爲美中不足。html5+
提供了一個XMLHttpRequest
模塊,在APP
端很完美的解決了這種問題,並且提供了和JavaScript XMLHttpRequest
對象用法相似的一系列屬性方法。因爲本文的重在在於講解html5+ XMLHttpRequest
,因此前面的JavaScript XMLHttpRequest
相關的屬性方法只是初略介紹了一下,下面重點介紹html5+ XMLHttpRequest
模塊。
因爲html5+ XMLHttpRequest
是一種拓展方案,因此須要底層支持,基於html5+ XMLHttpRequest
的方法不能用於非5+
環境,若是對這些概念不清楚的歡迎先閱讀我以前寫的文章mui初級入門教程(一)— 菜鳥入手mui的學習路線。
咱們用hbuilder
新建一個app工程,而後運行下面的代碼:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title></title> </head> <body> <script type="text/javascript"> document.addEventListener('plusready', function(){ var xhr = new plus.net.XMLHttpRequest(); xhr.onreadystatechange = function () { switch ( xhr.readyState ) { case 0: console.log( "xhr請求已初始化" ); break; case 1: console.log( "xhr請求已打開" ); break; case 2: console.log( "xhr請求已發送" ); break; case 3: console.log( "xhr請求已響應"); break; case 4: if ( xhr.status == 200 ) { alert( "xhr請求成功:"+xhr.responseText ); } else { console.log( "xhr請求失敗:"+xhr.readyState ); } break; default : break; } } xhr.open("GET", "https://www.baidu.com/"); xhr.send(); }, false ); </script> </body> </html>
咱們會發現最後彈出了彈框,裏面寫有百度首頁的代碼。
建立一個XMLHttpRequest
對象,對象建立時不觸發任什麼時候間和網絡請求,需和open
,send
方法配合使用。
var xhr = new plus.net.XMLHttpRequest(); xhr.open(method, url); xhr.send();
> XMLHttpRequest的屬性:
> XMLHttpRequest的方法:
> XMLHttpRequest的事件: