HTTP 协议演示_基于 HTTP 的 Web Forms 编程HTTP 协议(4
本文内容
- HTTP 请求
- HTTP 响应
- 服务器端抽象层
- 提交窗体
客户端向服务器端发送请求,服务器端接收并处理这个请求,返回给客户端。而HTTP协议定义客户端(Web浏览器)和服务器端(Web服务器)通信的机制。
HTTP 请求
当你将浏览器指向一个 URL 时,它利用域名服务系统(DNS)将 URL 提供的服务器名称翻译为一个IP地址。
接下来,浏览器打开一个套接字 Socket,连接到该 IP 地址的 80 端口。对 http://127.0.0.1/Default.aspx 下载请求的包具有下面这样简单的形式:
GET /Default.aspx HTTP/1.1
Host: 127.0.0.1HTTP 请求中通常包含许多头信息(Head):
- User-Agent - 识别发出请求的浏览器类型。
- Connection - 关闭连接或保持连接。
- If-Modified-Since - 提供客户端高速缓存验证。
HTTP 头信息是一行文本,提供有关请求的其他信息。文本的第一行是该请求的起始含,其中必须包含要执行的 HTTP 命令(如 GET)名称、资源 URL,以及目标 HTTP 协议版本。
觉不觉得跟第二篇文章中的代码段七有点像。另外,在IIS配置里,我们也可以找到关于HTTP头的设置,像“自定义HTTP头“、“MIME类型”等,如下图所示:
HTTP 响应
服务器的响应包括消息的协议版本和退出代码(说明成功或错误)组成的一个状态行。状态行的后面为一串头信息(通过为页面内容的类型和长度)和页面内容。一个空白行将页面内容和其余信息分来,如下所示:
HTTP/1.1 200 OK
Server:Microsoft-IIS / 5.0
Content-Type:text/html
Content-Length:51
<html><body><h1>ASP.NET is cool!</h1></body></html>
上述代码展示了由 Web 服务器返回的简单 HTML 输出。请求和响应是根据 HTTP 架构格式的字符串,通过TCP连接进行传输。代码为 200 表示对此请求的一切处理正常。指定的 Web 服务器处理该请求,根据给定的(MIME)类型(text/html)返回和具有一定长度的页面内容。
接下来的处理取决于 MIME 类型和浏览器的功能。只要MIME类型为 text/html,浏览器就将页面内容显示为HTML。
觉不觉得跟第二篇文章中的代码段八有点像。
服务器端抽象层
我们现在知道,客户端请求一个页面,然后服务器端响应这个请求,处理后再发给它。如果请求的是 .html 页面,就简单了,直接把页面放到数据包传过去就行,但 .aspx 页面怎么办?不可能直接发给客户端。那么在服务器端必须有一个抽象出来的东西(IIS进程)来完成这个工作。
Web 浏览器与 Web 服务器之间的每次会话都由类似于我们前面所说的数据包交换构成。一般地,如果客户端请求的 URL 是 .html 页面,Web 服务器读取该文件,将此文件内容刷新到响应的数据包中。如果 URL 为 ASP.NET 页面,就用一个专用的 IIS 模块。该模块是一个 ISAPI 扩展的 IIS 插件。一个 ISAPI 扩展是以文件扩展的方式注册的一个动态连接库(DLL)。任何时候,当某种资源类型的请求进入时,相应的 ISAPI 扩展将进行处理。
关于 ISAPI 我们也不陌生。下图 IIS 配置,.aspx 文件对应的动态连接库(DLL)文件为 aspnet_isapi.dll,它可以执行的动作有 GET、HEAD、POST 和 DEBUG;而 .shtm 和 .shtml 文件对应的 DLL 文件为 ssinc.dll,执行的动作只有 GET 和 POST,显然不能有 DEBUG。
当请求 .aspx 文件进入时,注册处理 .aspx 文件的 ISAPI 扩展将进行处理。
在配置 IIS 时,是不是曾经看过如下配置 IIS 的图。若禁止了 "所有未知 ISAPI",IIS 将无法识别 .aspx 文件。
处理 .aspx 页面的 ISAPI 扩展首先对在隐藏域(即调用上下文)中来回传送的会话状态进行反序列化处理。该信息用于配置创建页面输出的新实例化的控件。然后,保存在调用上下文与来自客户端控件(如文本框和复选框)的任何新信息进行合并。状态全部恢复后,就允许运行生成 HTML 输出。
但是处理 .aspx 文件不是这么简单的。要经过 IIS 几个进程的处理,这里暂时先不说。
提交窗体
HTML的 <form> 标记是唯一被授权将客户端数据传输到服务器的元素。当用户单击类型为 submit 的按钮时,根据设计,浏览器将数据该窗体的所有控件的当前内容填充到一个字符串,然后此字符串作为 GET 或 POST 命令的组成部分被传递到服务器。
现在我们在 .NET 中创建一个 .aspx 文件,内容如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html ="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<input id="Text1" type="text" />
<input id="Submit1" type="submit" value="submit" /></div>
</form>
</body>
</html>
浏览器源文件,内容如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html ="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Page</title>
</head>
<body>
<form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUJNzgzNDMwNTMzZGT8XigVHlmkk+BXiblfwYUp8bVAIA==" />
</div>
<div>
<input id="Text1" type="text" />
<input id="Submit1" type="submit" value="submit" /></div>
</form>
</body>
</html>
从代码中可见,该窗体与 POST 命令和 Default.aspx 这个 URL 相关联。
POST /Default.aspx HTTP/1.1
Host:127.0.0.1
Content-Type:application/x-www-form-urlencoded
Content-Length:12
Text1=1001
在处理页面请求时,ISAPI 扩展解析请求内容,将通过对程序员更友好的对象模型找到的任何信息进行公开。例如,不是继续使用简单的名称/值字符串,而是将 Text1 变量转移到一个应用程序级的集合,即 Request.Form 集合。这表示在原始 HTTP 编程模型上构建的第一级抽象。像 Request、Response、Server 这类对象组成了 HTTP 上下文。
TAG: