重要性:
是使用webservice
,仍是rest
作大型架构,都离不开对HTTP协议的认识javascript
简化的说:
webservice = http协议 + XML
Rest = http协议 + JSONphp
各类API,也是经过http + XML/JSON来实现css
作采集,须要对http协议有所了解,以及ajax,对http协议理解.html
计算机中的协议和现实中的协议是同样的,一式双份/多份
双方/多方都听从共同的一个规范,这个规范称之为协议.java
ftp, https, http, stmp, pop, tcp/ip 协议...git
URI/URL/URNgithub
// URL: 统一资源定位符 https://v.sf.com:80/index.html?name=user#bbs // URN:统一资源名称 ste.org/img.png
URI :统一资源标识符web
https默认寻找服务器443端口ajax
名词解释:apache
Open System Interconnnect
简称OSI)Transmission Control Protocol
传输控制协议)是一种面向链接的,可靠的,基于字节流的传输层通讯协议。Internet Protocol
)网络之间互连的协议Hyper Text Transfer Protocol
超文本传输协议)是互联网上应用最为普遍的一种网络协议。Hyper Text Transfer Protocol over Secure Socket Layer
)是以安全为目标的HTTP通道,简单讲师HTTP的安全版应用层(http/https/websocket/ftp) => 定义:文本传输协议 ↓ 传输层(tcp/udp) => 定义:端口 ↓ 网络层(IP) => 定义:IP ↓ 链路层(mac&数据包) => 定义:数据包,MAC地址 ↓ 实体层(光缆/电缆/交换机/路由/终端...) => 定义:物理
网络协议解释:
解释1:分别表明TCP协议和IP协议
解释2:若是按照网络五层架构,TCP/IP表明除了应用层其它层全部协议簇的统称
TCP/IP三次握手:
标有syn的数据包 -----------------> 标有syn/ack的数据包 client <----------------- server 标有ack的数据包 ----------------->
Keep-AliveHTTP
协议初期每次链接结束后都会断开TCP
连接,以后HEADER
的connection
字段定义Keep-Alive
(HTTP1.1 默认 持久链接),表明若是链接双方若是没有一方主动断开都不会断开TCP链接,减小了每次创建HTTP
链接时进行TCP
的链接的消耗.
当打开一个页面以后时.
客户端 --> 服务器 (请求链接)
链接:就是网络上的虚拟电路
客户端 <-- 服务器 (沿着链接,返回响应信息)
客户端,收到响应代码(HTML代码,解析文字,图片)
浏览器能发送HTTP协议,HTTP协议必定要浏览器来发送么?
不是,HTTP是一种协议,只要知足,什么工具均可以发送.
可使用 telnet host port
telnet做用:远程控制web服务器
回显功能:ctrl+]
输入以后,再回车
请求
请求行
使用telnet来完成HTTP协议的POST请求
POST /github/http/telnet_post.php HTTP/1.1 Host: www.muchai.com Content-type: application/x-www-form-urlencoded Content-length: 33
响应
响应行
请求方法有哪些?
GET, POST, HEAD, PUT, TRACE, DELETE, OPTIONS
HEAD和GET基本一致,只是不返回内容.
好比:只是确认一个内容(照片)是否还存在,不须要返回具体的内容。
PUT: 往服务器资源传输内容
TRACE:使用代理上网. 好比用代理访问www.sf.gg
看下代理是否修改HTTP请求,可使用TRACE来测试一下,sf.gg
的服务器就会把最后收到的请求返回.
OPTIONS: 返回服务器可用的请求方法.
注意:这些请求方法虽然是HTTP协议中规定的,但WEB SERVER未必容许或支持这些方法.
状态码和状态文字
状态码: 是用来反应服务器响应状况的
最多见的: 200 OK, 404 NOT FOUND,
状态文字是用来描述状态码,便于人观察
响应中的状态码
状态码 | 定义 | 说明 |
---|---|---|
1xx | 信息 | 接收到请求,继续处理 |
2xx | 成功 | 操做成功地收到请求,理解和接受 |
3xx | 重定向 | 为了完成请求,必须采起进一步措施 |
4xx | 客户端错误 | 请求的语法错误或不能彻底被知足 |
5xx | 服务端错误 | 服务器没法完成明显有效的请求 |
经常使用的状态码:
200 -- 服务器成功返回网页
301/2 -- 永久/临时重定向
<?php header('Location: http://www.sf.gg'); // 默认是 302 重定向 header('Location: http://www.sf.gg', true, 301); // 301 重定向 // 永久重定向 , true参数指的是用301头信息替换原来的头信息 ?>
304 Not Modified -- 未修改 (客户端告知服务器请求的资源,时间
和 ETag
是否变化)
307 重定向中保持原有的请求数据.(POST重定向以后,数据丢失)
失败的状态码:
404 -- 请求的网页不存在,地址错误。
403 -- 禁止访问,权限不足。
503 -- 服务器暂时不可用
500 -- 服务器内部错误
502(Bad Gateway) -- 网关错误(ip设置的时候网关地址错误)
常见通用头部
Cache-Control:
Pragma:
Connection:
常见请求头
Accept:能够处理的媒体类型和优先级
Host:目标主机域名
Referer: 请求从哪发起的原始资源URI
User-Agent:建立请求的用户代理名称
Coolie:cookie信息
常见响应头
Location: 重定向地址
Server: 被请求的服务web server的信息
Set-Cookie:要设置的cookie信息
概念:在http协议上增长了ssl(secure socket layer)层。
SSL层 ↓ 应用层 ↓ 传输层 ↓ 网络层 ↓ 链路层 ↓ 实体层
HTTPS认证流程
发起请求 ---------------------------> server 下发证书 <--------------------------- server 证书数字签名(用证书机构公钥加密) ---------------------------> 证书机构 证书数字签名验证经过 client(内置证书机构证书) <--------------------------- 证书机构 公钥加密随机密码串(将来的共享秘钥) ---------------------------> server私钥解密(非对称加密) SSL协议结束 HTTP协议开始 <--------------------------- server(对称加密) 共享秘钥加密 HTTP ---------------------------> server(对称加密)
https://
socket发送,HTTP请求.
/** * PHP + socket编程 ,发送HTTP请求 * * 模拟下载, 注册,登录, 批量发帖 */ // http请求类的接口 interface Proto { // 链接URL public function conn($url); // 发送get查询 public function get(); // 发送post查询 public function post(); // 关闭链接 public function close(); } class Http implements Proto { const CRLF = "\r\n"; // 换行信息 protected $errno = -1; // 错误编号 protected $errstr = ''; // 错误信息 protected $response = ''; // 响应内容 protected $urlInfo = null; // URL信息 protected $version = 'HTTP/1.1'; // 协议版本 protected $fh = null; // 句柄 protected $line = array(); // 请求行信息 protected $header = array(); // 请求头信息 protected $body = array(); // 请求主体信息 public function __construct( $url ) { $this->conn($url); // 设置头信息 $this->setHeader('Host: ' . $this->urlInfo['host']); } /** * 设置请求行 * @param {Stinrg} $method 请求方法 默认GET */ protected function setLine( $method ) { $this->line[0] = $method . ' ' . $this->urlInfo['path'] . ' ' . $this->version; } /** * 声明头信息 * @param {String} $headerline 头信息 */ protected function setHeader( $headerline ) { $this->header[] = $headerline; } /** * 写主体信息 * @param {Array} $body 设置body信息 */ protected function setBody( $body ) { $this->body[] = http_build_query($body); } /** * 链接URL * @param {String} $url 链接的URL */ public function conn( $url ) { // 分析URL $this->urlInfo = parse_url($url); // 判断端口 $this->urlInfo['port'] = isset($this->urlInfo['port']) && $this->urlInfo['port'] == 80 ? $this->urlInfo['port'] : 80; // 链接 $this->fh = fsockopen($this->urlInfo['host'], $this->urlInfo['port'], $this->errno, $this->errstr, 3); } /** * 构造get查询 */ public function get() { $this->setLine('GET'); $this->request(); return $this->response; } /** * 请求get数据 * 请求POST数据 */ public function request() { // 拼接请求信息 $req = array_merge($this->line, $this->header, array(''), $this->body, array('')); $req = implode(self::CRLF, $req); // 写 fwrite($this->fh, $req); // 读取 while ( !feof($this->fh) ) { $this->response .= fread($this->fh, 1024); } // 关闭链接 $this->close(); } /** * 构造post查询 * @param {Array} $body body 的信息 * */ public function post( $body=array() ) { // 设置请求行 $this->setLine('POST'); // 构造主体信息 $this->setBody($body); // 设置 Content-type 和 计算Content-length $this->setHeader('Content-type: application/x-www-form-urlencoded'); $this->setHeader('Content-length: ' . strlen($this->body[0])); $this->request(); return $this->response; } /** * 关闭链接 */ public function close() { fclose($this->fh); } } set_time_limit(0); // 设置脚本最大执行时间 // $url = 'http://luqi.baijia.baidu.com/article/719576'; $url = 'http://www.linxingzhang.com/index.php'; $http = new Http($url); // echo $http->get(); echo $http->post(array('tit' => 'xixi', 'con' => 'pink'));
须要的登录信息,提供请求信息,模拟提供.
// content $url = 'http://w.coral.qq.com/article/comment/'; $msg = array( 'targetid' => 1665529109, 'type' => 1, 'format' => 'SCRIPT', 'callback' => 'parent.topCallback', 'content' => 'backbone', '_method' => 'put', 'g_tk' => 1437957853, 'code' => 1, 'source' => 1, 'subsource' => 0, 'picture' => '' ); set_time_limit(0); $http = new Http($url); // 模拟头信息 $http->setHeader('cookie: ptui_loginuin=1129507496@qq.com; pt2gguin=o1129507496; uin=o1129507496; skey=@eHnHS7nT1; ptisp=ctc; RK=9gcWWrSXMK; ptcz=ad2886a1a4a2008cdf953cee396e4c18542dd5667d055f98c1cc7363fc1973ff; pac_uid=1_1129507496; o_cookie=1129507496; pgv_info=ssid=s595782189; pgv_pvid=6186477584; uid=324803742'); $http->setHeader('Referer: http://www.qq.com/coral/coralBeta3/coralMainDom3.0.htm'); $http->setHeader('Upgrade-Insecure-Requests:1'); $http->setHeader('User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'); // echo $http->post( $msg ); file_put_contents('./res.html', $http->post( $msg )); echo 'ook';
网站统计
网站统计结果,如何知道用户从那些渠道中进入本网站?
统计时,是如何得知用户从哪儿来到本网站?
在HTTP协议中,头信息里,有一个重要的选项:referer
referer:表明网页的来源,即上一页的地址.
若是直接在浏览器地址栏上输入,进入网页,则没有referer头.
如何配置apache服务器用于图片防盗链
原理:在web服务器层面,根据http协议的referer头信息来判断。若是来自站外,则统一重写到一个很小的防盗链提醒的图片上.(url重写)
mod_rewrite
。(打开mod_rewrite.so)LoadModule rewrite_module modules/mod_rewrite.so
开启后,支持重写模块.
* 在须要防盗的网站或目录,写.htaccess
文件,并指定防盗链规则.
如何指定,分析referer,若是不是来自本站,从写url.
重写规则
那种状况重写:
是jpeg/jpg/git/png图片时. 是referer头信息与localhost不匹配时重写.
> 如何重写
统一rewirte 到 某个防盗链图片.
.hatccess
文件:
RewriteEngine On RewriteCond %{REQUEST_FILENAME} .*\.(jpg|jpeg|git|png) [NC] RewriteCond %{HTTP_REFERER} !muchai.com [NC] RewriteRule .* http://linxingzhang.com/blog/img/weixin.jpg
采集
模拟referer
中的信息来请求数据.
$http = new Http('http://linxingzhang.com/blog/img/weixin.jpg'); $http->setHeader('Referer: http://www.muchai.com'); $res = $http->get(); file_put_contents('./xixi.jpg', substr(strstr($res, "\r\n\r\n"), 4));
图片的下载:
第一次请求 200ok
第二次请求 304 not modified(未修改状态)
在网络上有一些缓存服务器,浏览器自身也有缓存功能。
当第一次访问某图片时,正常下载图片,返回值200
基于一个前提(图片不会常常改动),服务器在返回200的同时,还返回该图片的"签名"Etag
. (签名:图片的指纹)
当浏览器再次访问的同时去服务器校验"指纹",若是图片没有变化。直接使用缓存中的图片.减轻的服务器的负担.
观察请求数据:
第一次访问
请求头:
相应头:
第二次请求
请求头
若是 自"Wed, 14 Dec 2016 15:41:45 GMT" 这个时间点之后,图片修改过,则从新请求。
若是图片最新的ETag的值和 If-None-Match的值不匹配则从新匹配,则从新请求。
响应头
若是是304时,浏览器从本地取值.
若是网站比较大,有N台缓存服务器,那么这N台服务器,主服务器如何处理主服务器上的文件
使用什么协议,来讲明这两个问题。
使用头信息,cache-control
来控制。
使用方法:
相关模块: mod_expires
.
在服务器,打开apache的expires
扩展. 利用该扩展,来控制图片,css,html等缓存的生存周期及是否缓存.
打开httpd.conf
配置项
LoadModule expires_module modules/mod_expires.so
在 .htaccess
文件配置中.
ExpiresDefault "<base> [plus] {<num> <type>}*" ExpiresByType type/encoding "<base> [plus] {<num> <type>}>*"
ExpiresDefault
是设置默认的缓存参数ExpiresByType
是按照文件类型来设置独特的缓存参数.
base
基于那个时间点计算缓存有效期
参数:
access/now: 基于请求响应的那一瞬间. (例如:今后瞬间到一个月以后)
modification: 基于被请求文件最后修改日期来计算. (例如:最后修改日期后一周内)
num: 缓存时间的大小 (例如:30)
type: 缓存的单位(例如:天)
给jpeg
图片设置一个月的缓存周期
ExpiresActive On ExpiresByType image/jpeg "access plus 30 days"
若是在集群环境里,缓存服务器获得此图片,将会认为在一个月内有效,减轻了主服务器的负担。
设置服务器,不让存在缓存.
例如:有些我的信息,不容许缓存服务器,必须到主服务器去请求.
Control-cache: no-store,must-revalidate; // 不容许缓存,必须去主服务器验证.
利用apache的header
模块
开启httpd.conf
中的header
模块
LoadModule headers_module modules/mod_headers.so
<FilesMatch "\.(jpg)$"> header set Cache-Control: "no-store,must-revalidate" </FilesMatch>
为了提升网页在网络上的传输速度.服务器对主体信息进行压缩.
常见的,gzip
压缩,deflate
压缩,compress
压缩以及sdch
压缩.
压缩的过程:
服务器返回压缩内容,客户端接收到压缩,再解压缩,再渲染页面.Content-Length
压缩后的长度
实际渲染的文件大小:
如何在apache启用的压缩功能?
deflate
模块,或者gzip
模块LoadModule deflate_module modules/mod_deflate.so
conf
文件中,配置:<ifmodule mod_deflate.c> DeflateCompressionLevel 6 AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/javascript AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/atom_xml AddOutputFilterByType DEFLATE application/x-javascript AddOutputFilterByType DEFLATE application/x-httpd-php AddOutputFilterByType DEFLATE image/svg+xml </ifmodule>
为何要指定文件类型压缩.
通常指定压缩文本格式的文件.
服务器如何知道浏览器支持gzip压缩
客户端容许发送Accept-Encoding
信息.与服务器协商.(协商头信息)
http协议+持久链接+分块传输 => 反向ajax
反向ajax又叫:comet,server push,服务器推技术.
应用范围:网页聊天服务器,新浪微博在线聊天,google mail网页聊天.
原理:HTTP协议的特色,链接--断开.
具体什么时间断开?
服务器响应content-length
,收到指定length长度的内容时,也就断开.
在http1.1协议中,容许不写content-length
。(好比要发送的内容长度确实不知道)这是,须要一个特殊的content-type
:chunked
分块传输:
<?php set_time_limit(0); ob_start(); $pad = str_repeat(" ", 4000); echo $pad, '<br />'; ob_flush(); flush(); // 把产生的内容当即返回给浏览器,而不要等待浏览器结束 $i = 1; while ( $i++ ) { echo $pad, '<br />'; echo $i, '<br />'; ob_flush(); flush(); sleep(1); } /** * * 即时通讯. * * 服务器端不间断,推送信息. 到客户端. */ ?>