網路程式設計-HTTP協議 response響應-解決跨域
阿新 • • 發佈:2019-01-09
HTTP/1.1 200 OK --響應行
Server: Apache-Coyote/1.1 --多個響應頭
Content-Length: 51
Date: Sun, 28 Dec 2014 01:51:16 GMT
--一個空行
this is first servlet!!Sun Dec 28 09:51:16 CST 2014 --實體內容(使用者直接看到的內容)
一,響應行
HTTP/1.1 http協議版本資訊
狀態碼:伺服器對於請求處理的結果
其中常用的狀態碼的含義:
200: 表示請求處理完成。
302: 表示請求需要進一步細化。通常該狀態碼和location響應頭結合使用。
404: 表示客戶端錯誤,找不到資源。
500: 表示伺服器錯誤。
其中不常用的也在此告訴大家:
|"100" ; 10.1.1節: 繼續
|"101" ; 10.1.2節: 轉換協議
|"200" ; 10.2.1節: OK
|"201" ; 10.2.2節: 已建立
|"202" ; 10.2.3節: 接受
|"203" ; 10.2.4節: 非權威資訊
|"204" ; 10.2.5節: 無內容
|"205" ; 10.2.6節: 重置內容
|"206" ; 10.2.7節: 部分內容
|"300" ; 10.3.1節: 多個選擇
|"301" ; 10.3.2節: 永久移動
|"302" ; 10.3.3節: 發現
|"303" ; 10.3.4節: 見其它
|"304" ; 10.3.5節: 沒有被改變
|"305" ; 10.3.6節: 使用代理
|"307" ; 10.3.8節 臨時重發
|"400" ; 10.4.1節: 壞請求
|"401" ; 10.4.2節: 未授權的
|"402" ; 10.4.3節: 必要的支付
|"403" ; 10.4.4節: 禁用
|"404" ; 10.4.5節: 沒有找到
|"405" ; 10.4.6節: 方式不被允許
|"406" ; 10.4.7節: 不接受的
|"407" ; 10.4.8節: 需要代理驗證
|"408" ; 10.4.9節: 請求超時
|"409" ; 10.4.10節; 衝突
|"410" ; 10.4.11節: 不存在
|"411" ; 10.4.12節: 長度必需
|"412" ; 10.4.13節;先決條件失敗
|"413" ; 10.4.14節: 請求實體太大
|"414" ; 10.4.15節; 請求URI太大
|"415" ; 10.4.16節: 不被支援的媒體型別
|"416" ; 10.4.17節: 請求的範圍不滿足
|"417" ; 10.4.18節: 期望失敗
|"500" ; 10.5.1節: 伺服器內部錯誤
|"501" ; 10.5.2節: 不能實現
|"502" ; 10.5.3節: 壞閘道器
|"503" ; 10.5.4節: 服務不能獲得
|"504" ; 10.5.5節: 閘道器超時
|"505" ; 10.5.6節: HTTP版本不支援
二,響應頭:
Location: http://www.it315.org/index.jsp --重定向地址。通常和302狀態碼配合使用,完成請求重定向效果
Server:apache tomcat --伺服器型別
Content-Encoding: gzip --伺服器傳送給瀏覽器的資料壓縮格式
Content-Length: 80 --伺服器傳送給瀏覽器資料長度
Content-Language: zh-cn --伺服器傳送給瀏覽器資料語言
Content-Type: text/html; charset=GB2312 --伺服器傳送給瀏覽器資料型別
Last-Modified: Tue, 11 Jul 2000 18:23:51GMT --伺服器資源最後修改時間
Refresh: 1;url=http://www.it315.org --定時重新整理或每隔n秒跳轉頁面
Content-Disposition: attachment; filename=aaa.zip --告訴瀏覽器以下載方式開啟資源
Transfer-Encoding: chunked
Set-Cookie:SS=Q0=5Lb_nQ; path=/search --伺服器傳送給瀏覽器的cookie資訊
Expires:-1 --建議瀏覽器不使用快取
Cache-Control:no-cache
Pragma:no-cache
Connection: close/Keep-Alive --伺服器和瀏覽器連線狀態。close:關閉連線。keep-alive:保持連線。
Date: Tue, 11 Jul 2000 18:23:51 GMT --響應傳送的時間
傳統的跨域請求沒有好的解決方案,無非就是jsonp和iframe,隨著跨域請求的應用越來越多,W3C提供了跨域請求的標準方案(Cross-Origin Resource Sharing)。IE8、Firefox 3.5 及其以後的版本、Chrome瀏覽器、Safari 4 等已經實現了 Cross-Origin Resource Sharing 規範,實現了跨域請求。在伺服器響應客戶端的時候,帶上Access-Control-Allow-Origin頭資訊。
如PHP新增響應頭資訊:
傳統的Ajax請求只能獲取在同一個域名下面的資源,但是HTML5打破了這個限制,允許Ajax發起跨域的請求。瀏覽器是可以發起跨域請求的,比如你可以外鏈一個外域的圖片或者指令碼。但是Javascript指令碼是不能獲取這些資源的內容的,它只能被瀏覽器執行或渲染。
在Flash和Silverlight中,伺服器需要建立一個crossdomain.xml的檔案來允許跨域請求。如果這個檔案宣告“http://your.site”允許來自“http://my.site”的請求,則來自“http://my.site”的請求可以訪問所有“http://your.site”的檔案。這是一種整個站點層面上的控制模式,要麼你允許一個外域的站點訪問,要麼拒絕。
COR不一樣,它是頁面層次的控制模式。每一個頁面需要返回一個名為‘Access-Control-Allow-Origin’的HTTP頭來允許外域的站點訪問。你可以僅僅暴露有限的資源和有限的外域站點訪問。在COR模式中,訪問控制的職責可以放到頁面開發者的手中,而不是伺服器管理員。當然頁面開發者需要寫專門的處理程式碼來允許被外域訪問。
另外一個主要的區別是,某個站點的crossdomain.xml檔案是最早被瀏覽器獲取並分析的。如果一個外域的站點不允許被訪問,瀏覽器壓根就不會發出跨域請求。
COR則相反,Javascript先發出跨域請求,然後檢查回覆的‘Access-Control-Allow-Origin’頭。如果這個頭允許該外域訪問,則Javascript可以讀取這個回覆,否則就被禁止訪問。如果請求不是一個簡單的COR,則向外域伺服器傳送預檢驗請求,如果回覆的頭部允許訪問,則傳送跨域請求,否則禁止。
COR的實現標準就是CORS協議。
對於瀏覽器來說,COR請求都是Javascript發起的,COR請求有兩種:
1、簡單的COR請求,它可以直接向外域資源發起請求。它必須僅僅包含簡單的方法和頭,具體定義看[2] 6.1。
2、如果COR包含複雜的方法和頭,它需要發出預檢驗(Preflight)請求,它先向資源伺服器發出一個OPTIONS方法、包含“Origin”頭的請求。該回復可以控制COR請求的方法,HTTP頭以及驗證等資訊。只有該請求獲得允許以後,才會發起真實的外域請求。
下面是一個簡單的COR請求:
<script language="Javascript" type="text/javascript">
var client = new XMLHttpRequest();
client.open("GET", "http://bar.org/b")
client.onreadystatechange = function() { /* do something */ }
client.send()
</script>
假設這個請求所在頁面的域是“http://foo.org”。 如果來自“http://bar.org/b”的回覆包含這樣的頭:
Access-Control-Allow-Origin: http://foo.org
則表明,它允許來自“http://foo.org”的跨域請求。
下面的Javascript會發出預檢驗請求和真實請求:
<script language="Javascript" type="text/javascript">
var client = new XMLHttpRequest();
client.open("GET", "http://bar.org/b")
client.setRequestHeader('Content-Type','text/html')
client.onreadystatechange = function() { /* do something */ }
client.send()
</script>
由於“Content-type: text/html”不是一個簡單的頭,它會先向"http://bar.org/b"發出一個OPTIONS的HTTP請求。 回覆可能包含這樣的頭:
Access-Control-Allow-Origin: http://foo.org
Access-Control-Max-Age: 3628800
Access-Control-Allow-Methods: GET,PUT, DELETE
Access-Control-Allow-Headers: content-type
"Access-Control-Allow-Origin"表明它允許"http://foo.org"發起跨域請求
"Access-Control-Max-Age"表明在3628800秒內,不需要再發送預檢驗請求,可以快取該結果
"Access-Control-Allow-Methods"表明它允許GET、PUT、DELETE的外域請求
"Access-Control-Allow-Headers"表明它允許跨域請求包含content-type頭
如果預檢驗請求獲得通過,接下來Javascript就會發起真實的COR請求,過程跟簡單的COR請求類似。
CORS協議的實現
現在HTML5的標準如火如荼的在制定和發展中,CORS作為HTML5的一部分,在大部分現代瀏覽器中有所支援,支援(部分支援)CORS協議的瀏覽器有IE8+, Firefox5+, Chrome12+, Safari4+
服務端實現
Thinktecture.IdentityModel 這個庫已經為我們的WebAPI,MVC的專案做好了支援,具體參看[6]。
參考資料:
[1] http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
[2] http://www.w3.org/TR/cors/
[3]Cross-origin_resource_sharing
[4]跨域資源共享(Cross-Origin Resource Sharing)實現Ajax跨域請求
[5]http://restfulobjects.codeplex.com/wikipage?title=Cross%20Origin%20Resource%20Sharing&referringTitle=Documentation
[6]CORS support in WebAPI, MVC and IIS with Thinktecture.IdentityModel
三,響應實體由後臺指定內容發出。
HttpServletResponse物件用於設定響應資訊。
常用方法:
響應行:
response.setStatus(); 設定狀態碼
響應頭:
response.setHeader(name,value); 設定響應頭
實體內容
response.getWriter().writer() 以字元格式傳送實體內容
response.getOutputStream().writer() 以位元組格式傳送實體內容
修改響應資料的方法。