HTTP权威指南阅读笔记三:HTTP报文
报文的组成部分
报文由三部分组成:对报文进行描述的起始行(start line)、包含属性的首部(header),以及可选的、包含数据的主体(body)部分。
请求报文格式
<method> <request-URL> <version>
<headers>
<entity-body>
响应报文格式
<version> <status> <reson-phrase>
<headers>
<entity-body>
HTTP方法
主要的HTTP方法有:
方法 | 描述 | 是否包含主体 |
GET | 从服务器获取一份文档 | 否 |
HEAD | 只从服务器获取文档的首部 | 否 |
POST | 向服务器发送需要处理的数据 | 是 |
PUT | 将请求的主体部分存储在服务器上 | 是 |
TRACE | 对可能经过代理服务器传送到服务器上去的报文进行追踪 | 否 |
OPTIONS | 决定可以在服务器上执行哪些方法 | 否 |
DELETE | 从服务器上删除一份文档 | 否 |
另外,HTTP1.1允许扩展规范中没有的方法。
示例
js部分:
var httpMethodTest = (function () { "use strict"; var _xhr = new XMLHttpRequest(); var _sendXHR = function (method, url, callback) { _xhr.onreadystatechange = function () { if (_xhr.readyState === 4 && _xhr.status === 200) { callback(_xhr); } }; _xhr.open(method, url, true); _xhr.send(''); }; var get = function (url, callback) { _sendXHR("GET", url, callback); }; var put = function (url, callback) { _sendXHR("PUT", url, callback); }; var post = function (url, callback) { _sendXHR("POST", url, callback); }; var head = function (url, callback) { _sendXHR("HEAD", url, callback); }; var trace = function (url, callback) { _sendXHR("TRACE", url, callback); }; var options = function (url, callback) { _sendXHR("OPTIONS", url, callback); }; var deleteMethod = function (url, callback) { }; return { get: get, put: put, post: post, head: head, trace: trace, options: options, deleteMethod: deleteMethod }; })(); var btnGET = document.getElementById("btnGET"), btnPOST = document.getElementById("btnPOST"), btnPUT = document.getElementById("btnPUT"), btnHEAD = document.getElementById("btnHEAD"), btnOPTIONS = document.getElementById("btnOPTIONS"), btnTRACE = document.getElementById("btnTRACE"), headerResultNode = document.getElementById("headerResult"), bodyResultNode = document.getElementById("bodyResult"), headerTitleNode = document.getElementById("headerTitle"), bodyTitleNode = document.getElementById("bodyTitle"); btnGET.onclick = function () { headerTitleNode.innerHTML = "GET Response Headers:"; bodyTitleNode.innerHTML = "GET Response Body:"; httpMethodTest.get("/home/Test?t=" + Math.random(), methodResult); } btnPOST.onclick = function () { headerTitleNode.innerHTML = "POST Response Headers:"; bodyTitleNode.innerHTML = "POST Response Body:"; httpMethodTest.post("/home/Test?t=" + Math.random(), methodResult); } btnPUT.onclick = function () { headerTitleNode.innerHTML = "PUT Response Headers:"; bodyTitleNode.innerHTML = "PUT Response Body:"; httpMethodTest.put("/home/Test?t=" + Math.random(), methodResult); } btnHEAD.onclick = function () { headerTitleNode.innerHTML = "HEAD Response Headers:"; bodyTitleNode.innerHTML = "HEAD Response Body:"; httpMethodTest.head("/home/Test?t=" + Math.random(), methodResult); } //由于ajax中不可以直接发trace请求,所以这里改为发get请求,然后在controller中作代理发trace请求 btnTRACE.onclick = function () { headerTitleNode.innerHTML = "TRACE Response Headers:"; bodyTitleNode.innerHTML = "TRACE Response Body:"; httpMethodTest.get("/home/Trace?url=" + encodeURIComponent("http://xxxxx/test.php") + "&t" + Math.random(), methodResult); } btnOPTIONS.onclick = function () { headerTitleNode.innerHTML = "OPTIONS Response Headers:"; bodyTitleNode.innerHTML = "OPTIONS Response Body:"; httpMethodTest.options("/home/Test?t=" + Math.random(), methodResult); } //从XMLHttpRequest中取出Header及Body数据 function methodResult(xhr) { var header = {}, response = "", results = []; header["status"] = xhr.status; header["statusText"] = xhr.statusText; header["Cache-Control"] = xhr.getResponseHeader("Cache-Control"); header["Content-Type"] = xhr.getResponseHeader("Content-Type"); header["Allow"] = xhr.getResponseHeader("Allow"); header["Content-Encoding"] = xhr.getResponseHeader("Content-Encoding"); header["Vary"] = xhr.getResponseHeader("Vary"); header["Server"] = xhr.getResponseHeader("Server"); header["Date"] = xhr.getResponseHeader("Date"); header["Content-Length"] = xhr.getResponseHeader("Content-Length"); for (var key in header) { if (header[key]) { results.push("<li>" + key + ": " + header[key] + "</li>"); } } headerResultNode.innerHTML = results.join(""); bodyResultNode.value = xhr.responseText; }
页面部分:
<div> <input type="button" id="btnGET" value="GET" /> <input type="button" id="btnPOST" value="POST" /> <input type="button" id="btnPUT" value="PUT" /> <input type="button" id="btnHEAD" value="HEAD" /> <input type="button" id="btnTRACE" value="TRACE" /> <input type="button" id="btnOPTIONS" value="OPTIONS" /> </div> <h3 id="headerTitle">Response Headers:</h3> <ul id="headerResult" class="list-txt"> </ul> <h3 id="bodyTitle">Response Body:</h3> <textarea id="bodyResult" class="list-txt" rows="5" disabled="disabled"></textarea>
controller中发送trace请求:
public void Test() { Response.ClearContent(); if (Request.HttpMethod.Equals("OPTIONS")) { Response.AddHeader("Allow", "GET, POST, PUT, DELETE, TRACE, OPTIONS"); } else { Response.Write("This is a " + Request.HttpMethod); } Response.End(); } public void Trace(string url) { HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(url); httpWReq.Method = "TRACE"; httpWReq.ContentType = "application/x-www-form-urlencoded"; HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse(); string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); Response.ClearContent(); Response.Write(responseString); Response.End(); }
运行结果:
get/put/post的header及body类似,也很常见,这里就不帖图了
HEAD
TRACE
OPTIONS