书接上回
上次我们讲了对接API是件多么复杂的事情,认证手段和花样非常多,非常复杂。
今天我们来讲讲HTTP头部(HEADER)。
什么是HTTP 头部
HTTP协议其实是个很LOW的协议。他其实跟你写信的逻辑是一样的。就是把请求一行行的写在文本里,然后发给对方,对方一行行解析出来,再去做对应的逻辑。这些协议都是INTERNET TEXT MESSAGES(很多早期设计的互联网协议都是如此,包括SMTP, FTP, WHOIS, IRC,定义于RFC822)。
这类协议其实都是用一行行的文本去表示自己要做什么的。
本质山,你可以用一个TCP客户端用底层TCP协议连接到一个HTTP服务器上。
比如我们用Linux下的NC客户端,连接到一个HTTP服务器上,然后手工去执行HTTP请求。

这个过程其实和你在浏览器中,使用调试器看见的请求过程是一样的。

所以看起来,HTTP请求是不是就跟 写了一封信去询问一个东西一样?
那么,我们就可以简单的说,HTTP 头部其实就是在正文(body)之前的一些附加信息,附加说明本次请求的一些情况,比如请求方法是什么,请求路径是什么,我想要的返回格式是什么等(Accept),这些要求都是一个Key后面跟一个冒号,然后跟上具体内容构成的。
HTTP头部定义要求
前面我们讲了在这种文本协议中,头部是一个Key后面跟一个冒号,然后跟上具体内容构成的一些关于请求的属性说明,那怎么保证发送的和接收的都明白对方呢,这就是HTTP协议又具体要定义的东西。

上面是HTTP RFC中定义的一些标准的头部。
大家可以看看这些定义格式上有什么共同点。
是不是都是大写开头,并且以-连接在一起?
这可以说是我在对接API过程中见过最奇特的坑了。
因为这种奇特的英语逻辑,中国人哪能理解这种要求。所以你可以发现各种各样不符合这种规范的API要求,比如要求提供”key“的,”requesst-key”的,“requestKey”的,按道理应该也无所谓。
偏偏有些语言还要预置修正这些“不正确”(我查了原始RFC,其实没有硬性要求必须这么做,所以严格意义上讲不是不正确)的头部。
比如Golang:
request, _ := http.NewRequest("GET", fakeurl, nil) request.Header.Add("MyKey", "MyValue") request.Header.Add("MYKEY2", "MyNewValue") request.Header.Add("DONT-CHANGE-ME","No")
1
2
3
4
直接调用Header.Add的时候,会强制进行格式转换,上面的DONT-CHANGE-ME直接会变成Dont-Change-Me,见标准文件(net/textproto)header.go下面的代码,中间的CanonicalMIMEHeaderKey就是干这个用的。
// Add adds the key, value pair to the header. // It appends to any existing values associated with key. func (h MIMEHeader) Add(key, value string) { key = CanonicalMIMEHeaderKey(key) h[key] = append(h[key], value) }
1
2
3
4
5
6
这种错,对接API的时候,找错能郁闷死你,服务端始终接不到,发送的还查不到错,要是不用抓包工具看,根本查不出来。

关键是,现在大部分都https化了,想抓个包都越来越难了。
难搞的Content-Type
除了这些自定义属性之外,还有个常见的属性容易出问题。
Content-Type这东西,按标准是用来标识资源的MIME类型,最开始HTTP简单的时候,通常text/html是指html文件,除此之外,图片(image/jpeg等最多)。
application/soap+xmlapplication/json
容易出错的是请求格式,因为大家很容易就会忽略掉对这个Header的说明。

比如Gitee的这个接口,你第一反应是什么格式提交呢?我们点一下测试


applicaton/x-www-form-urlencoded
这时的请求body是这样的值:
access_token=1231&description=123&files=123&public=true

经常性的会遇到没有说明这个问题的情况。
还经常性的会遇到要求输入json但是要求你一定要提交为text/html的,或者返回的时候不指定Contet-Type但是当application/json返回的。
说多了都是泪。
下期继续
API接口趣事多,百家饭隐私计算提供基于OpenAPI的API分享调试工具,已经开放注册了哦,我是百家饭的刘铭。