http相关知识 - (3)Get - Post 不同
1. URL
(1) URL解释
①. 基本解释
URL: 统一资源定位符,具体的URL地址。
Uniform Resource Locator. 是浏览器寻找信息时的资源位置,通过URL才能够找到共享因特网上的资源。
URI : 统一资源标识符,用来唯一的标识资源。
Uniform Resource Identifiter.
URN: 唯一标识一个实体的标识符,但是不能给出实体的位置。
Uniform Resource Name
.系统可以先在本地寻找一个实体,在它试着在Web上找到该实体之前。它也允许Web位置改变,然而这个实体却还是能够被找到。
详情请看: 你知道URL、URI和URN三者之间的区别吗?
② URL的构成(或许应该说是URI的组成)
(1)
Scheme: 协议
(2)
//: 层级url的标识符号
(3)
Login:password@: 身份验证
(4)
Address: 域名部分,也可以是ip地址
(5)
Port: 服务器端口
(6)
/path/to/resource: 文件路径
(7)
?query_string: 查询参数
(8)
#fragment: 片段,锚点
2. Get - Post 不同的地方
(1)关于Get - Post在RFC文档的原文介绍
①Get
The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.
GET 方法意思是获取被请求 URI(Request-URI)指定的信息(以实体的格式)。如果请求URI 涉及到一个数据生成过程,那么这个过程生成的数据应该被作为实体在响应中返回而不是过程的源文本,除非源文本恰好是过程的输出。
The semantics of the GET method change to a “conditional GET” if the request message includes an If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network usage byallowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client.
如果请求消息包含 If-Modified-Since,,If-Unmodified-Since,If-Match,If-None-Match 或者If-Range 头域,GET 的语义将变成“条件(conditionall) GET”。一个条件 GET 方法会请求满足条件头域的实体。条件GET 方法的目的是为了减少不必要的网络使用,这通过允许利用缓存里仍然保鲜的实体而不用多次请求或传输客户端已经拥有的实体来实现的。
The response to a GET request is cacheable if and only if it meets the requirements for HTTP caching described in
section 13.
GET 请求的响应是可缓存的(cacheable)如果此响应满足第13 节 HTTP缓存的要求。
②Post
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. POST is designed to allow a uniform method to cover the following functions:
• Annotation of existing resources;
• Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles;
• Providing a block of data, such as the result of submitting a form, to a data-handling process;
• Extending a database through an append operation.
POST 方法被用于请求源服务器接受请求中的实体作为请求资源的一个新的从属物。POST被设计涵盖下面的功能。
• 已存在的资源的注释;
• 发布消息给一个布告板,新闻组,邮件列表,或者相似的文章组。
• 提供一个数据块,如提交一个表单给一个数据处理过程。
• 通过追加操作来扩展数据库。
The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.
POST 方法的实际功能是由服务器决定的,并且经常依赖于请求 URI(Request-URI)。POST提交的实体是请求 URI的从属物,就好像一个文件从属于一个目录,一篇新闻文章从属于一个新闻组,或者一条记录从属于一个数据库。
Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.
POST 方法的响应是不可缓存的。除非响应里有合适的 Cache-Control 或者 Expires 头域。然而,303(见其他)响应能被用户代理利用去获得可缓存的资源。
③Encoding Sensitive Information in URI’s
Authors of services which use the HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data, because this will cause this data to be encoded in the Request-URI. Many existing servers, proxies, and user agents will log the request URI in some place where it might be visible to third parties. Servers can use POST-based form submission instead.
使用 HTTP 协议的服务者不应该使用基于 GET方式 提交敏感数据,因为这个能引起数据在请求 URI里被编码。许多已存在的服务,代理,和用户代理将在对第三方可见的地方记录请求URI。服务器能响应基于 POST 方式的form提交来取代基于GET 方式的提交。
(2). Customer Diference
a. Get用来获取数据,post用来发送数据实体到接收者。
b. Post的安全性高于get。
c. 通过RFC文档的描述,我们可以看出Get的方式就是将data放在url后面进行传送的,post是放在request body中进行传送的。
但是从http实现的角度上讲,对于get,post的方式来说,是可以互通的,这里的互通是指,可以用get的方式发送post,post的方式发送get。
① 普通get方式请求
② Server对普通get方式请求获取的数据(注释里是当前字符串的值)
③ 以post(将参数放在requestBody中)的方式发送get请求
④ 我们再看一下现在这种方式的请求在server种的值获取情况
⑤ 再看一下post的正常请求
⑥ 看一下server的情况
⑦ 以get的方式(将参数放在url种)发送post请求
⑧ 再看一下server的情况
Summary:通过上面的例子可以看到当get,post都将参数放在url中的时候在server得到的值是一样。对于get,post都将参数放在request body中的时候,requestBodyString的值是一样的,这就说明get post都通过requestbody传参数时其实是一样的都支持,至于不相同的值,我猜测是asp.net对于这几个值得赋值的问题,因为requestBody内的原始数据参数字符串我们都是可以拿到的。
d. Get是可缓存的,Post是不可以缓存的(除非手动设置)。
① 我们先看一下Get的缓存: 请看下方图片红色标注的地方,看一下
size和
time两个地方
②然后我们刷新一下页面,再看一下各个文件的读取情况,可以看到下方图片种绿色框里的请求,都是从cache种读取的。至于这个实现的原因,大家可以搜索一下Last-Modified 与If-Modified-Since就可以知道了。至于cache的相关问题,后面说道jquery或者js的时候会统一总结学习一下。
③ 现在看一下对于ajax get请求json的缓存。以asp.net mvc 为例,对于get json请求,服务端的默认response 的cache是private的,需要显示的设置一些header。
前段代码: 其中ifModified对应的是If-Modified-Since,只是jquery自己的封装罢了。可以显示的写出来,也可以不写,因为默认值是false。要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。
$("#get_action").click(function () {
$.ajax({
url: '/Http/GetAction',
type: 'GET',
//ifModified: false,
success: function (data) {
console.log(data);
},
error: function (err) {
}
})
});
服务端代码:
public ActionResult GetAction(string username)
{
var queryString = HttpContext.Request.QueryString; // queryString: {}
var formString = HttpContext.Request.Form; // formString: {}
var urlString = HttpContext.Request.Url.ToString(); // urlString: http://localhost:30403/Http/GetAction
#region 获取post参数
//这里获取post参数,我们可以使用这个获取get方式,将参数放在requestBody中时内部的值。
byte[] byts = new byte[Request.InputStream.Length];
Request.InputStream.Read(byts, 0, byts.Length);
string requestBodyString = System.Text.Encoding.Default.GetString(byts);
requestBodyString = Server.UrlDecode(requestBodyString); //requestBodyString: "username=Rod+Chen"
#endregion
Response.Cache.SetExpires(DateTime.Now.AddSeconds(5));
Response.Cache.SetLastModified(DateTime.Now);
Response.Cache.SetCacheability(HttpCacheability.Public);
return Json(new
{
Name = "Rod Chen",
Company = "Augmentu"
}, JsonRequestBehavior.AllowGet);
}
大家只需要关注Response.Cache就可以了,因为上面的代码在前面的内容谈到过。这样的话我们就可以实现了get json的缓存。然后让我们看一下浏览器在访问这个action的读取情况。下图中可以看到第一个request是发送到server的,而第二个是从缓存中读取的,第三个是先发送到server,check Last-Modified 与If-Modified-Since的值之后再从缓存中读取的。大家也可以看一下各个请求所花费的时间。这边之所以会有这样的现象是因为我们在上面的代码中这是了过期时间是第一个请求的5s之后,再有请求来就会重新那一次server的数据。想详尽链接的,可以打开 大叔手记(20):ASP.NET MVC中使用jQuery时的浏览器缓存问题
Summary:
GET请求(静态文件)会被浏览器主动cache,对于json实体需要进行一些处理(从我自己的测试来看)。
POST不会,除非手动设置。处理非idempotent request请求和区别idempotent request和非idempotent request请求,可以实现对Post的缓存。当然为了进一步提高效率,可以使用缓存握手的方式,在互联网上只发送摘要,在客户端和正向代理以及反向代理和服务端之间的局域网类发送完整的消息体。大家有兴趣的话可以去了解一下缓存 HTTP POST请求和响应。
(3) Summary difference
总结一下从RFC文档中我所看到的的不同之处:
a. Get用来获取数据,post用来发送数据实体到接收者。
b. Post的安全性高于get。
c. 通过RFC文档的描述,我们可以看出Get的方式就是将data放在url后面进行传送的,post是放在request body中进行传送的。
d. Get是可缓存的,Post是不可以缓存的(除非手动设置)。
还有一些虽然不是RFC自己定义的,是浏览器或者不同的语言对于两种请求的处理,但是还是根据RFC中的定义和语境来定义的,也可以当做是分别,当然看大家从哪个角度看了。
GET在浏览器回退时是无害的,而POST会再次提交请求。
GET产生的URL地址可以被Bookmark,而POST不可以。
GET请求只能进行url编码,而POST支持多种编码方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST么有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET方式,服务器端用Request.QueryString获取变量的值,对于POST方式,服务器端用Request.Form获取提交的数据。