HTTP协议简介
既然是基于HTTP协议开发,那么就首先要了解下HTTP协议的相关内容~html
在TCP/IP体系结构中,HTTP属于应用层协议,位于TCP/IP协议的顶层。浏览Web时,浏览器经过HTTP协议与Web服务器交换信息。这些信息(文档)类型的格式由MIME定义。git
HTTP协议具备如下的特色:github
一次HTTP操做称为一次事务(transaction)。 |
HTTP请求的格式以下所示:数组
1 <request-line> 2 <headers> 3 <blank line> 4 [<request-body>]
在HTTP请求中,第一行必须是一个请求行(request line),用来讲明请求类型、要访问的资源以及使用的HTTP版本。紧接着是一个首部(header)小节,用来讲明服务器要使用的附加信息。在首部以后是一个空行,再此以后能够添加任意的其余数据[称之为主体(body)]。
在HTTP中,定义了大量的请求类型,不过Ajax开发人员关心的只有GET请求和POST请求。只要在Web浏览器上输入一个URL,浏览器就将基于该URL向服务器发送一个GET请求,以告诉服务器获取并返回什么资源。对于URL为XXX的GET请求以下所示:浏览器
1 GET / HTTP/1.1 2 Host: XXX 3 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) 4 Gecko/20050225 Firefox/1.0.1 5 Connection: Keep-Alive
请求行的第一部分说明了该请求是GET请求。该行的第二部分是一个斜杠(/),用来讲明请求的是该域名的根目录。该行的最后一部分说明使用的是HTTP 1.1版本(另外一个可选项是1.0)。那么请求发到哪里去呢?这就是第二行的内容。
第2行是请求的第一个首部,HOST。首部HOST将指出请求的目的地。结合HOST和上一行中的斜杠(/),能够通知服务器请求的是XXX(HTTP 1.1才须要使用首部HOST,而原来的1.0版本则不须要使用)。第三行中包含的是首部User-Agent,服务器端和客户端脚本都可以访问它,它是浏览器类型检测逻辑的重要基础。该信息由你使用的浏览器来定义(在本例中是Firefox 1.0.1),而且在每一个请求中将自动发送。最后一行是首部Connection,一般将浏览器操做设置为Keep-Alive)。注意,在最后一个首部以后有一个空行。即便不存在请求主体,这个空行也是必需的。缓存
若是要获取一个诸如XXX/xxx的XXX域内的页面,那么该请求可能相似于:服务器
1 GET /xxx/ HTTP/1.1 2 Host: XXX 3 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) 4 Gecko/20050225 Firefox/1.0.1 5 Connection: Keep-Alive
要发送GET请求的参数,则必须将这些额外的信息附在URL自己的后面。其格式相似于:网络
该信息称之为查询字符串(query string),它将会复制在HTTP请求的请求行中,以下所示app
1 GET /xxx/?name=Professional%20Ajax HTTP/1.1 2 Host: XXX 3 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) 4 Gecko/20050225 Firefox/1.0.1 5 Connection: Keep-Alive
如下就是一个典型的POST请求:异步
1 POST / HTTP/1.1 2 Host: XXX 3 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) 4 Gecko/20050225 Firefox/1.0.1 5 Content-Type: application/x-www-form-urlencoded 6 Content-Length: 40 7 Connection: Keep-Alive 8 name=Professional%20Ajax&publisher=Wiley
正如前面所提到的,还有其余的HTTP请求类型,它们听从的基本格式与GET请求和POST请求相同。下一步咱们来看看服务器将对HTTP请求发送什么响应。
HTTP响应
以下所示,HTTP响应的格式与请求的格式十分相似:
1 <status-line> 2 <headers> 3 <blank line> 4 [<response-body>]
正如你所见,在响应中惟一真正的区别在于第一行中用状态信息代替了请求信息。状态行(status line)经过提供一个状态码来讲明所请求的资源状况。如下就是一个HTTP响应的例子:
1 HTTP/1.1 200 OK 2 Date: Sat, 31 Dec 2005 23:59:59 GMT 3 Content-Type: text/html;charset=ISO-8859-1 4 Content-Length: 122 5 6 <html> 7 <head> 8 <title>Wrox Homepage</title> 9 </head> 10 <body> 11 <!-- body goes here --> 12 </body> 13 </html>
在本例中,状态行给出的HTTP状态代码是200,以及消息OK。状态行始终包含的是状态码和相应的简短消息,以免混乱。最经常使用的状态码有:
在状态行以后是一些首部。一般,服务器会返回一个名为Date的首部,用来讲明响应生成的日期和时间(服务器一般还会返回一些关于其自身的信息,尽管并不是是必需的)。接下来的两个首部你们应该熟悉,就是与POST请求中同样的Content-Type和Content-Length。在本例中,首部Content-Type指定了MIME类型HTML(text/html),其编码类型是ISO-8859-1(这是针对美国英语资源的编码标准)。响应主体所包含的就是所请求资源的HTML源文件(尽管还可能包含纯文本或其余资源类型的二进制数据)。浏览器将把这些数据显示给用户。
注意,这里并无指明针对该响应的请求类型,不过这对于服务器并不重要。客户端知道每种类型的请求将返回什么类型的数据,并决定如何使用这些数据
WebRequest类
WebRequest 是 .NET Framework 的用于访问 Internet 数据的请求/响应模型的抽象基类。使用该请求/响应模型的应用程序能够用协议不可知的方式从 Internet 请求数据。在这种方式下,应用程序处理 WebRequest 类的实例,而协议特定的子类则执行请求的具体细节。
请求从应用程序发送到某个特定的 URI,如服务器上的 Web 页。URI 从一个为应用程序注册的WebRequest 子代列表中肯定要建立的适当子类。注册 WebRequest 子代一般是为了处理某个特定的协议(如 HTTP 或 FTP),可是也能够注册它以处理对特定服务器或服务器上的路径的请求。
因为 WebRequest 类是一个抽象类,因此 WebRequest 实例在运行时的实际行为由 WebRequest.Create 方法所返回的子类肯定。
注意 使用 Create 方法初始化新的 WebRequest 实例。不要使用 WebRequest 构造函数。
下面的示例说明如何建立 WebRequest 实例并返回响应。
1 // Initialize the WebRequest. 2 WebRequest myRequest = WebRequest.Create("xxx"); 3 // Return the response. 4 WebResponse myResponse = myRequest.GetResponse(); 5 // Code to use the WebResponse goes here. 6 // Close the response to free resources. 7 myResponse.Close();
WebResponse 类
WebResponse 类是抽象(在 Visual Basic 中为 MustInherit)基类,协议特定的响应类从该抽象基类派生。应用程序可使用 WebResponse 类的实例以协议不可知的方式参与请求和响应事务,而从 WebResponse 派生的协议特定的类携带请求的详细信息。
客户端应用程序不直接建立 WebResponse 对象,而是经过调用 WebRequest 实例上的GetResponse 方法来建立它。
下面的示例从 WebRequest 建立 WebResponse 实例。
1 // Initialize the WebRequest. 2 WebRequest myRequest = WebRequest.Create("xxx"); 3 // Return the response. 4 WebResponse myResponse = myRequest.GetResponse(); 5 // Code to use the WebResponse goes here. 6 // Close the response to free resources. 7 myResponse.Close();
HttpWebRequest 类
HttpWebRequest 类对 WebRequest 中定义的属性和方法提供支持,也对使用户可以直接与使用 HTTP 的服务器交互的附加属性和方法提供支持。
不要使用 HttpWebRequest 构造函数。使用 WebRequest.Create 方法初始化HttpWebRequest 的一个新实例。若是 URI 的方案是 http://
或 https://
,则 Create 将返回 HttpWebRequest 实例。
GetResponse 方法向 RequestUri 属性中指定的 Internet 资源发出同步请求并返回包含该响应的HttpWebResponse 实例。可使用 BeginGetResponse 和 EndGetResponse 方法对 Internet 资源发出异步请求。
当要向 Internet 资源发送数据时,GetRequestStream 方法返回用于发送数据的Stream实例。BeginGetRequestStream 和 EndGetRequestStream 方法提供对发送数据流的异步访问。
下面的示例为 URI xxx 建立 HttpWebRequest
1 HttpWebRequest myReq =(HttpWebRequest)WebRequest.Create("xxx");
经过调用 GetResponseStream 方法,以 Stream 的形式返回来自 Internet 资源的响应的内容。
下面的示例返回 HttpWebRequest 的 HttpWebResponse:
1 HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create("xxx"); 2 HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse(); 3 // Insert code that uses the response object. 4 HttpWResp.Close()
1 Uri siteUri = new Uri("xxx"); 2 WebRequest wr = WebRequest.Create(siteUri);
建立一个test的aspx页面
建立获取请求方法
1 public string GetPost() 2 { 3 if ("POST" == Request.RequestType) 4 { 5 System.IO.Stream sm = Request.InputStream;//获取post正文 6 int len = (int)sm.Length;//post数据长度 7 byte[] inputByts = new byte[len];//字节数据,用于存储post数据 8 sm.Read(inputByts, 0, len);//将post数据写入byte数组中 9 sm.Close();//关闭IO流 10 //**********下面是把字节数组类型转换成字符串********** 11 string data = Encoding.GetEncoding("UTF-8").GetString(inputByts);//转为unicode编码 12 //data = Server.UrlDecode(data);//url参数用到. 13 return data; 14 } 15 else 16 return null; 17 }
在Load中使用Response
1 string res = GetPost(); 2 Response.Write(res);
新建一个解决方案调用上述程序
Main方法中代码以下所示:
1 string ss = "hello world!"; 2 Encoding encoding = Encoding.GetEncoding("utf-8"); 3 byte[] bytesToPost = encoding.GetBytes(ss); 4 string res = Post("http://localhost:23094/test.aspx", bytesToPost); 5 Console.WriteLine(res); 6 Console.ReadLine();
其中Post方法传入url和bytesToPost
1 private static string Post(string url, byte[] bytesToPost) 2 { 3 if (String.IsNullOrEmpty(url)) 4 return "url参数为空值"; 5 if (bytesToPost == null) 6 return "post数据为空值"; 7 string ResponseString = ""; 8 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 9 System.Net.ServicePointManager.DefaultConnectionLimit = 50; 10 request.KeepAlive = false; 11 request.Method = "POST"; 12 request.ContentType = "text/xml";//提交xml 13 request.ContentLength = bytesToPost.Length; 14 Stream writer = request.GetRequestStream(); 15 writer.Write(bytesToPost, 0, bytesToPost.Length); 16 HttpWebResponse HttpWebRespon = (HttpWebResponse)request.GetResponse(); 17 StreamReader myStreamReader = new StreamReader(HttpWebRespon.GetResponseStream(), Encoding.UTF8); 18 ResponseString = myStreamReader.ReadToEnd(); 19 myStreamReader.Close(); 20 21 writer.Flush(); 22 if (writer != null) 23 { 24 writer.Close(); 25 } 26 if (request != null) 27 { 28 request.Abort(); 29 } 30 return ResponseString; 31 }
效果,先运行Demo 程序再运行调用程序便可看到以下效果
请求成功,返回结果
PS:具体代码执行过程你们能够下完Demo后自行debug看看,代码灰常简单,算是最简单的http请求和响应以及调用的流程了,在复杂的过程也是基于这个流程来执行的
https://github.com/XiaoYong666/Http-interface-call
注:介绍部份内容转载摘抄自网络,如有文章雷同,请评论留言~定会及时注明出处