一、HTTP连接流程
客户端向服务器建立连接,发送请求
服务器沿着连接,返回响应信息
客户端收到响应HTML代码,解释出图片,文字
客户端和服务器断开连接
二、HTTP请求
HTTP请求包括请求行、请求头信息、请求主体信息
1、请求行
请求行又分为:请求方法,请求路径,请求的协议
如:GET /0606/01.php HTTP/1.1
2、请求方法
请求方法有:GET、HEAD、POST、DELETE、TRACE、OPTIONS...
🔑方法解释:
①、GET:通常用于请求服务器发送某些资源
②、HEAD:获取资源的头部信息,获取的头部信息和GET一致
适用于只是确认一个内容(比如照片)还正常存在(或者文件大小等),不需要返回照片的内容,这时用HEAD比较合适
③、TRACE:回显服务器收到的请求,主要用于测试或诊断
当你用了代理上网,比如用代理访问ew.163.com
,你想看看代理有没有修改你的HTTP请求。可以用TRACE来测试一下,163.com
的服务器就会把最后收到的请求返回给你
④、OPTIONS:返回服务器可用的请求方法(有些请求方法虽然HTTP协议里规定的,但WEB SERVER未必允许或支持这些方法)
⑤、POST:发送数据给服务器
GET和POST的区别
方法 | get | post |
---|---|---|
数据长度 | 参数放在URL上,由于URL的长度有限,因此能提交的数据内容也很有效。 | 数据或参数放在body中,body可接纳的数据量远大于直接放在URL上 |
数据类型 | 只支持文本(ASCII字符),并且采用urlencode | 支持文本,采用urlencode,也支持二进制,能够用来传输文件 |
HTTP请求例子如:
请求:
请求行(请求方法 路径 协议)
头信息(格式为key:value)
空行
主体信息(可选,发送内容)
例子:
GET /0606/01.php HTTP/1.1
Host:localhosts
Content-type:
application x-www-form-urlen #没有这一行不行
code
Cotent-length:5
Age=3
响应信息:
响应行(协议版本 状态码 状态文字)
响应头信息(格式为key:value)
空行
主体信息(也可能没有)
例子:
HTTP/1.1 200 OK
Date:Thu.06 Jun 2013 12:39:02 GMT
Server:Apache/2.2.21 <Win32>PHP/5.3.8
X-Powered-By:PHP/5.3.8
Content-Length:5 #接下来主体长度
Content-Type:text/html
hello
状态码、状态文字
状态码是用来反应服务器响应情况的
最常见的如200 OK,404N0TF0ND
状态文字是用来描述状态码的便于人观察
状态码 | 定义 | 说明 |
---|---|---|
1XX | 信息 | 接收到请求,继续处理 |
2XX | 成功 | 操作成功地收到,理解和接受 |
3XX | 重定向 | 为了完成请求,必须采取进一步措施 |
4XX | 客户端错误 | 请求的语法有错误或不能完全被满足。 |
5XX | 服务端错误 | 服务器无法完成明显有效的请求。 |
HTTP中响应的状态码:
- 200-服务器成功返回网页
- 301/2-永久/临时重定向
- 304 Not Modified-未修改(发送到重定向的页面后可能会丢失数据,要用307)
- 307-重定向中保护原有的请求数据
失败的状态码:
- 404-请求的网页不存在
- 503-服务器暂时不可用
- 500-服务器内部错误
三、socket编程发送GET请求
代码没有运行过,只为学习
//http请求类接口
interface proto{
//连接url
function conn($url);
//发送get查询
function get();
//发送post查询
function post();
//关闭连接
function close();
}
class Http implements Proto{
const CRLF = "\r\n";//const只读,不能修改
protected $url = null;//存储parse_url拆分出来的url
protected $fh = null;//fsockopen返回的文件句柄,可被fread等函数使用
protected $version = 'HTTP/1.1'
//定义数组存储请求信息
protected $line = array();
protected $header = array();
protected $body = array();
//fescopen参数
protected $errno = -1;
protected $errst = '';
public function __construct($url){
$this->conn($url);
$this->setHeader('Host:'.$this->url['path']);
}
//写请求行
protected function setLine($method){
$this->line[0] = $method.' '.$this->url['path'].''.$this->version;//拼接成请求行
}
//写头信息
protected function setHeader($headline){
$this->header[] = $headline;
}
//写主体信息
protected function setBody(){
//可以为空
}
//连接url
public function conn($url){
//分析url
$url = parse_url($url);
//判断端口
if(!isset($this->url['port'])){
$this->url['port'] = 80;
}
$this->fh = fsockopen($this->url['host'],$this->url['port'],$this->errno,$this->errst,3);
}
//构建get请求的数据
public function get(){
$this->setLine('GET');
$this->setHeader();
}
//发送post查询
public function post($body = array()){
}
//真正请求
public function request(){
//合并数组,变成一个完整的请求,便于拼接
$req = array_merge($this->line,$thisd->header,array(''),$this->body,array(''));
fwrite($this->fh,$req);
$req = implode(self::CRLF,$req);//用implode将数组拼接成字符串
fread($this->fh);
$this->close();
}
//关闭连接
public function close(){
fclose($this->fh);
}
}
$url = "http://baidu.com"
$http->get();
//print_r($http);
四、socket编程批量发帖
相对于发送GET请求,POST请求需要多加主体信息,即发帖的内容(标题,文本)
//写主体信息
protected function setBody($body){
$this->body[] = http_build_query($body);
}
//发送post查询
public function post($body = array()){
//构造主体信息
$this->setLine("POST");
//设置主体信息,比GET不一样的地方
$this->setBody($body);
//设置content-type
$this->setHeader('Content-type:application/x-www-form-urlencoded');
//计算content-length
$this->setHeader(strlen($this->body[0]))
$this->request();
}
public function request(){
//合并数组,变成一个完整的请求,便于拼接
$req = array_merge($this->line,$thisd->header,array(''),$this->body,array(''));
fwrite($this->fh,$req);
fread($this->fh);
}
$url = 'http://liangyue.net.cn/0523/?';
$http = new http($url);
post(array('tit'=>'zhangsan','con'=>'haha','sumbit'=>'留言'));
五、HTTP协议模拟登录发贴
首先要发帖,需要登录账号,那么就需要使用cookie登录进去,而且浏览器会分析你的头信息,需要使用整个头信息,才能够比较好的伪装成用户。
$http = new http('http://biadu.com');
$http->setHeader('cookie:...');
$http->setHeader('Referer:...');
$http->setHeader('User-Agent:...');
$msg = array(
'formhash'=>'...',
'message'=>'Hello World',
......
)
$http->post($msg);
六、referer头与防盗链
当在网页引用站外图片时,常常出现显示不出图片的情况,这是因为在HTTP中,有一个重要的选项:referer,referer代表网页来源,即上一页的地址,如果时直接在浏览器上输入地址,回车进来,则没有referer头。
配置apache服务器,用于图片防盗链
-
原理:在web服务器层面,根据HTTP协议的referer头信息,来判断是否来自站外,如果来自站外,则统一重写到一个很小的防盗链提醒图片上。
-
具体步骤:
- 打开apache重写模块mod_rewrite链规则
- 在需要防盗的网站或目录,写.htaccess文件,并指定防盗
-
重写规则
- 是jpeg/jpg/gif/png图片时,如果referer头与localhost不匹配时,则重写
七、HTTP缓存详解
我们打开图片时,往往:
第一次请求时:200 OK
第二次请求时: 304 Not Modify
解释:在网络上,有一些缓存服务器,浏览器自身也有缓存功能,当我们第一次打开某图片时,正常打开图片,返回值200,但基于一个前提——图片不会经常改动,服务器返回200的同时,还返回该图片的“签名”——Etag,当浏览器在此访问该图片时,去服务器校验签名,如果图片没有变化,直接使用缓存中的图片,这样减轻了服务器的负担。
八、HTTP内容压缩
原理:为了提高网页在网络上的传输速度,服务器对主体信息进行压缩,如常见的gzip压缩,deflate压缩,compress压缩以及google chrome正在推的sdch压缩。
-
在apache启动压缩功能
1、开启deflate,或gzip模块
2、在conf文件中,写如下代码:
DeflateCompressionLevel 6 #压缩级别为6,可选1-9,推荐6
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/ xml
问:为什么要指定文件类型来压缩?
答:压缩也是要消耗CPU资源,图片/视频等文件,一般压缩文本格式