Http Header
HTTP 消息头 Headers 是 HTTP 协议的一项重要内容,作用是在发起请求的时候,除了请求参数外,可以附加更多的信息。
关于
Headers的更多资料,属于课外阅读的知识,感兴趣的同学可以点击链接阅读 HTTP Headers文档
Headers 信息并不是写在 URL 中的,属于隐藏的数据,不能直观看到。
不一定任何利用JAVA的请求都能成功,例如我们在浏览器中输入 IP 地址详情信息查询的 API :
https://www.fastmock.site/mock/3d95acf3f26358ef032d8a23bfdead99/api/service/getIpInfo.php?ip=117.89.35.58&format=json
在浏览器中是可以看到结果的。
但是用 Java 程序调用却不行。请看下列代码演示:
可以看到,console 中虽然有结果,但实际上没有需要的内容。
这是因为像 taobao.com 这样的大型网站,处于安全等各种因素考虑,会对请求进行比较严格的校验,其中一个重要的校验,是判断请求是否真的来自于一个真实的浏览器。
如果不是来自浏览器,例如 Java 程序请求,API 服务器认为不是真实的浏览器访问,就直接拒绝掉了。
判断请求是否真的来自于一个真实的浏览器,需要从 HTTP 消息头(Headers)中取得 User-Agent 信息后,才能判断。
User—Agent
User-Agent 是存放在 Headers 中的一种数据信息。作用是,在指定 URL 发送请求的时候,告诉服务端当前用户的浏览器类型、版本,甚至操作系统、CPU等非隐私的技术信息。
服务器从 Headers 中的 User-Agent 信息获取到浏览器类型、版本等数据后,就认为是一个浏览器请求的环境了,就会给出响应。
关于
User-Agent的详细资料 —— User-Agent文档
所以,我们只要在程序代码中,附加上 User-Agent 信息,就能允许成功了。当然,这里的 User-Agent 是模拟的。我们来模拟一个 win7 + chrome 的环境,User-Agent 的写法如下:
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1
具体的含义这里就不赘述了,用到的时候查文档就好了。
模拟了一个 User-Agent ,程序中怎么用呢?实际上 Okhttp3 库已经支持 Headers 了,只需要在构建 Request 对象的时候,调用 addHeader() 方法即可:
Request request = new Request.Builder()
.url(url)
.addHeader("User-Agent", "")
.build();
addHeader() 方法第一个参数是名称,第二个参数是值。
在 console 中已经打印了响应的结果。
Referer
图片防盗链检查。
例如下列图片:
我们可以看到,图片无法正常显示,因为图片服务器做了“防盗链”。
图片网址是:https://cdn.nlark.com/yuque/0/2019/png/93870/1571386626984-2462f7f9-d397-4e50-91e4-e4b688dd3410.png
拷贝图片网址贴到浏览器地址栏,是可以访问的。
如何防盗链呢?
因为浏览器在请求网页中的图片(或其它任何文件)时,会自动在 HTTP 消息头 Headers 中,加一个 Referer 信息,表示请求的来源(或者可以理解为图片的上级是网页)。
浏览器自动加“Referer”是业界规范,是默认的行为,不容易干预
即浏览器自动告诉图片服务器,从当前 youkeda.com 请求此图片,这时图片服务器拒绝了访问,因为图片服务器的规则是不允许其它网站(非nlark.com)访问图片。
为什么直接贴网址可以访问?
因为直接拷贝网址、粘贴到浏览器地址栏,就没有“来源”了。此时不是网页中加载图片,而是浏览器直接加载图片,图片没有上级。
浏览器不是上级,浏览器是浏览网页的工具而已。换句话说,“来源”、“上级”指的是访问的具体内容。
上一节学过的“User-Agent”就表示用什么样的浏览器工具。
图片服务器允许无 Referer 信息时访问,就可以看到图片了。也就是说,决定权仍然在“图片服务器”,不同公司的服务器规则不同,不能一概而论。
浏览器只是收集一些信息提交到服务器,并不能决定是否能看到图片
程序中的 Referer
为了模拟浏览器自动加 Referer 信息的行为,可以调用语句:
Request request = new Request.Builder()
.url(url)
.addHeader("Referer", "https://ham.youkeda.com/course/j14/0")
.build();
同样,程序访问此图片也是失败的,请看下面解决方法中的演示程序:
http 响应状态码是:403 ,表示禁止访问此图片。
解决办法
贴到浏览器能访问是因为此图片服务器允许无 Referer 信息时访问。但也不是所有图片服务器都允许呢,况且即使同一个图片服务器,也可能修改规则,某一天突然改为必须本站内才能也未可知。
所以,为了一劳永逸的解决问题,需要把 Referer 信息设置为图片原始使用的网站。
程序中如何知道 Referer 值?
敬请期待 . . . . . .
Host
Host也是 Headers 中非常重要的信息之一。
Host 表示当前请求的域名。虽然这个域名已经存在于 URL 中,但遇到复杂的场景,例如使用代理服务器、或者 URL 中不写域名而是写 IP 地址进行请求等,设置 Host 就非常有用了。
由于 Host 的作用和含义比较宽泛,就不能确定各种网站的服务端会拿 Host 做什么,可以有很多作用。所以当前的学习阶段会用就可以了。
关于
Host的详细资料,属于课外阅读的知识,感兴趣的同学可以点击链接阅读 Host文档
跟 User-Agent 和 Referer 一样,Host 也是属于 Headers 数据的字段之一:
Request request = new Request.Builder()
.url(url)
.addHeader("Host", "www.douban.com")
.build();
注意,Host 的值一定是一个域名且不带协议头。