HTTP琐碎知识点

2018-08-01更

操作cookie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var CookieUtil = {
get:function (name) {
var cookieName = encodeURIComponent(name)+"=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if(cookieStart > -1){
var cookieEnd = document.cookie.indexOf(";",cookieStart);
//所取为最后一个键值对
if(cookieEnd == -1){
cookieEnd = document.cookie.length;
}
//截取value的值
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart+cookieName.length,cookieEnd));
}
return cookieValue;
},
set:function (name,value,expire,path,domain,secure) {
var cookieText = encodeURIComponent(name)+"="+encodeURIComponent(value);

if(expire instanceof Date){
cookieText += "; expire=" + expire.toGMTString();
}
if(path){
cookieText += "; path=" + path;
}
if(domain){
cookieText += "; domain=" + domain;
}
if(secure){
cookieText += "; secure"
}
document.cookie = cookieText
},
unset: function (name,path,domin,secure) {
this.set(name,"",new Date(0),path,domin,secure);
}
}

2018-07-04更

get和post的区别

  1. get使用url或cookie传参,而post将数据放在body中。
  2. get方式提交数据有长度限制,而post的数据可以很大。
  3. post比get安全,因为数据在地址栏上不可见。
  4. get和post最大的区别主要是GET请求是幂等性的,POST请求不是。

什么是幂等性?幂等性是指一次和多次请求某一个资源应该具有同样的副作用。简单来说意味着对同一URL的多个请求应该返回同样的结果。

正因为它们有这样的区别,所以不应该且不能用get请求做数据的增删改这些有副作用的操作。因为get请求是幂等的,在网络不好的隧道中会尝试重试。如果用get请求增数据,会有重复操作的风险,而这种重复操作可能会导致副作用(浏览器和操作系统并不知道你会用get请求去做增操作)。

http与https区别

  1. https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
  2. http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
  3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
  4. http的连接很简单,是无状态的;HTTPS协议是由SSL(Secure Sockets Layer) +HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

内容协商

内容协商机制是指客户端和服务器端就响应的资源内容进行交涉,然后提供给客户端最为合适的资源。内容协商会以响应资源的语言、字符集、编码方式等作为判断的基准。

基准

包含在请求报文中的某些字段就是判断的基准:

  • Accept
  • Accept-Charset
  • Accept-Encoding
  • Accept-Language
  • Content-Language

内容协商技术

服务器驱动协商(Server-driven Negotiation)

由服务器端进行内容协商。以请求的首部字段为参考,在服务器端自动处理。但对用户来说,以浏览器发送的信息作为判定的依据,并不一定能筛选出最优内容。

客户端驱动协商(Agent-driven Negotiation)

由客户端进行内容协商的方式。用户从浏览器显示的可选项列表中手动选择。还可以利用javascript脚本在web页面上自动进行上述选择。比如按OS的类型或者浏览器的类型,自动切换成PC页面或手机版页面。

透明协商(Transparent Negoyiation)

是由服务器启动和客户端驱动的结合体,是由服务端和客户端各自进行内容协商的一种方法。

压缩传输的内容编码

内容编码指明应用在实体内容上的编码格式,并保持实体信息鸳鸯压缩。内容编码后的实体由客户端接收并负责解码。

常用的内容编码:

  • gzip(GNU zip)
  • compress(UNIX系统的标准压缩)
  • deflate(zlib)
  • identity(不进行编码)

url详解

文章来源-url详解

直接举个例子:

1
http://www.easywork.xin:8080/news/index.asp?boardID=5&ID=24618&page=1#name

协议部分

该url的协议部分为http:,表示用的是HTTP协议,使用“//”做分隔符。

域名部分

该url的域名部分为www.easywork.xin,域名等同于IP。

端口部分

跟在域名后面的是端口,域名与端口之间使用”:”作为分隔符,端口不是一个url必须的部分,如果省略了端口,则使用默认端口。

虚拟目录部分

从域名后的第一个”/“开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个url必须的部分。本例中的虚拟目录为/news/

文件名部分

从域名后的最后一个“/”开始到“?”为止,是文件部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,是文件名部分。本例中的文件名是index.asp。文件名部分也不是一个url必须的部分,如果省略该部分,则使用默认的文件。

参数部分

从“?”开始到“#”为止之间的部分都是参数部分,又称搜索部分,查询部分。本例中的参数部分为boardID=5&ID=24618&page=1。参数可以允许有多个参数,参数之间用“&”作为分隔符。

锚部分

从“#”开始到最后,是锚部分,本例中的锚部分是“name”。锚部分也不是一个url必须的部分,这部分主要用于页内定位,定位到特定的DOM节点。

四种常见的POST提交数据方式

四种常见的POST提交数据方式

HTTP请求报文格式如下:

HTTP协议规定,post提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式,开发者可以自己决定消息主体的格式。但是,数据发送出去,还要服务端解析成功才有意义。服务端通常是根据请求头(headers)中的Content-Type字段来获知请求中的消息主体是何种方式编码,再对主体进行解析。所以POST提交数据方案,包含了Content-Type和消息主题编码方式两部分。

application/x-www-form-urlencoded

浏览器的原生

表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded方式提交数据
。请求类似于下面这样(无关的请求头在本文中都省略掉了):

1
2
3
4
BASHPOST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

首先,Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。

很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQueryQWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」。

multipart/form-data

我们使用表单上传文件时,必须让

表单的 enctype 等于 multipart/form-data
。直接来看一个请求示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
BASHPOST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。

这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。

上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生

表单也只支持这两种方式(通过 元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded。其实 enctype 还支持 text/plain,不过用得非常少)。

application/json

application/json 这个Content-Type作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

Google 的 AngularJS 中的 Ajax 功能,默认就是提交 JSON 字符串。例如下面这段代码:

1
2
3
4
JSvar data = {'title':'test', 'sub' : [1,2,3]};
$http.post(url, data).success(function(result) {
...
});

最终发送的请求是:

1
2
3
4
BASHPOST http://www.example.com HTTP/1.1 
Content-Type: application/json;charset=utf-8

{"title":"test","sub":[1,2,3]}

这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。各大抓包工具如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示 JSON 数据,非常友好。

text/xml

文本方式的xml文件,text/xml忽略xml头所指定编码格式而默认采用US-ASCII编码。 XML 结构过于臃肿,一般场景用 JSON 会更灵活方便。