资讯专栏INFORMATION COLUMN

PHP_HTTP协议

ziwenxie / 1184人阅读

摘要:网络之间互连的协议超文本传输协议是互联网上应用最为广泛的一种网络协议。使用什么协议,来说明这两个问题。

HTTP协议介绍

重要性:
是使用webservice,还是rest做大型架构,都离不开对HTTP协议的认识

简化的说:
webservice = http协议 + XML
Rest = http协议 + JSON

各种API,也是通过http + XML/JSON来实现

做采集,需要对http协议有所了解,以及ajax,对http协议理解.

协议

计算机中的协议和现实中的协议是一样的,一式双份/多份
双方/多方都遵从共同的一个规范,这个规范称之为协议.

ftp, https, http, stmp, pop, tcp/ip 协议...

URI/URL/URN

// URL: 统一资源定位符
https://v.sf.com:80/index.html?name=user#bbs

// URN:统一资源名称
ste.org/img.png

URI :统一资源标识符

URN和URL都属于URI.

URI能成为URL的当然就是那个“访问机制”,“网络位置”

URN是唯一标识的一部分,就是一个特殊的名字

https默认寻找服务器443端口

名词解释:

OSI:开放系统互连参考模型(Open System Interconnnect 简称OSI)

TCP:TCP (Transmission Control Protocol 传输控制协议)是一种面向连接的,可靠的,基于字节流的传输层通信协议。

IP:IP(Internet Protocol)网络之间互连的协议

HTTP:HTTP(Hyper Text Transfer Protocol超文本传输协议)是互联网上应用最为广泛的一种网络协议。

HTTPS:HTTPS (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-Alive
HTTP协议初期每次连接结束后都会断开TCP链接,之后HEADERconnection字段定义Keep-Alive(HTTP1.1 默认 持久连接),代表如果连接双方如果没有一方主动断开都不会断开TCP连接,减少了每次建立HTTP连接时进行TCP的连接的消耗.

HTTP协议工作流程

当打开一个页面之后时.

原始状态 : 客户端与服务器之间没有关系

request 请求

客户端 --> 服务器 (请求连接)
连接:就是网络上的虚拟电路

response 响应

客户端 <-- 服务器 (沿着连接,返回响应信息)

客户端,收到响应代码(HTML代码,解析文字,图片)

断开连接

浏览器能发送HTTP协议,HTTP协议一定要浏览器来发送么?
不是,HTTP是一种协议,只要满足,什么工具都可以发送.
可以使用 telnet host port
telnet作用:远程控制web服务器

回显功能:
ctrl+]输入之后,再回车

请求信息和响应信息

请求

请求行

请求头信息

请求主体信息 (可以没有)

头信息结束后和主体信息之间要空行一行

请求行

请求方法
请求方法:GET,POST,PUT,HEAD,DELTE,TRACE,OPTIONS

请求路径

所用的协议: 目前一般是HTTP/1.1 0.9 和 1.0 基本不使用

使用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未必允许或支持这些方法.

get: 获取资源,url传参,大小2KB

post: 传输资源,http body, 大小默认8M,1000个input variable

put: 传输资源,http body,资源更新

delete: 删除资源

patch: 传输资源,http body,存在的资源局部更新

head: 获取http header

options: 获取支持的method

trace: 追踪,返回请求回环信息

connect: 建立隧道通信

状态码

状态码和状态文字

状态码: 是用来反应服务器响应情况的
最常见的: 200 OK, 404 NOT FOUND,
状态文字是用来描述状态码,便于人观察

响应中的状态码

状态码 定义 说明
1xx 信息 接收到请求,继续处理
2xx 成功 操作成功地收到请求,理解和接受
3xx 重定向 为了完成请求,必须采取进一步措施
4xx 客户端错误 请求的语法错误或不能完全被满足
5xx 服务端错误 服务器无法完成明显有效的请求

常用的状态码:
200 -- 服务器成功返回网页
301/2 -- 永久/临时重定向

304 Not Modified -- 未修改 (客户端告知服务器请求的资源,时间ETag是否变化)
307 重定向中保持原有的请求数据.(POST重定向之后,数据丢失)

失败的状态码:
404 -- 请求的网页不存在,地址错误。
403 -- 禁止访问,权限不足。
503 -- 服务器暂时不可用
500 -- 服务器内部错误
502(Bad Gateway) -- 网关错误(ip设置的时候网关地址错误)


200: ok

301: 永久重定向

302: 临时重定向

303: 临时重定向,要求用get请求资源

304: not modified, 返回缓存,和重定向无关

307: 临时重定向,严格不从post到get

400: 参数错误

401: 未通过http认证

403: forbidden,未授权

404: not found,不存在资源

500: internet server error,代码错误

502: bad gateway,fastcgi返回的内容web server不明白

503: service unavailable,服务不可用

504: gateway timeout,fastcgi响应超时

Header Fields

常见通用头部

Cache-Control:

no-cache: 不缓存过期的缓存

no-store: 不缓存

Pragma:

no-cache: 不使用缓存,http1.1前的历史字段

Connection:

控制不在转发给代理首部字段

Keep-Alive/Close:持久连接

Date: 创建http报文的日期

常见请求头

Accept:可以处理的媒体类型和优先级
Host:目标主机域名
Referer: 请求从哪发起的原始资源URI
User-Agent:创建请求的用户代理名称
Coolie:cookie信息

常见响应头

Location: 重定向地址
Server: 被请求的服务web server的信息
Set-Cookie:要设置的cookie信息

NAME:要设置的键值对

expires:cookie过期时间

path: 指定发送cookie的目录

domain: 指定发送cookie的域名

Secure: 指定之后只有https下才发送cookie

HostOnly:指定之后javascript无法读取cookie

HTTPS

概念:在http协议上增加了ssl(secure socket layer)层。

SSL层
↓
应用层
↓
传输层
↓
网络层
↓
链路层
↓
实体层

HTTPS认证流程

                     发起请求
                     --------------------------->  server 
                              下发证书
                      <---------------------------   server 
                      证书数字签名(用证书机构公钥加密)
                     --------------------------->  证书机构 
                          证书数字签名验证通过
client(内置证书机构证书) <---------------------------   证书机构
                      公钥加密随机密码串(未来的共享秘钥)
                     --------------------------->  server私钥解密(非对称加密)
                        SSL协议结束 HTTP协议开始
                      <---------------------------   server(对称加密)
                            共享秘钥加密 HTTP
                     --------------------------->  server(对称加密)

核对证书:证书机构的公开密钥验证整数的数字签名

公开密钥加密建立连接:非对称加密

共享密钥加密

HTTP2

多路复用:多个请求共享一个tcp连接

全双工通信

必须https://

头部压缩

二进制传输

socket编程

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 = "
"; // 换行信息 
        
        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"));
http协议模拟登陆

需要的登陆信息,提供请求信息,模拟提供.

    // 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";
referer头与防盗链

网站统计

网站统计结果,如何知道用户从那些渠道中进入本网站?
统计时,是如何得知用户从哪儿来到本网站?

在HTTP协议中,头信息里,有一个重要的选项:referer
referer:代表网页的来源,即上一页的地址.
如果直接在浏览器地址栏上输入,进入网页,则没有referer头.

如何配置apache服务器用于图片防盗链

原理:在web服务器层面,根据http协议的referer头信息来判断。如果来自站外,则统一重写到一个很小的防盗链提醒的图片上.(url重写)

apache重写模块 mod_rewrite。(打开mod_rewrite.so)

LoadModule rewrite_module modules/mod_rewrite.so
开启后,支持重写模块.

* 在需要防盗的网站或目录,写.htaccess文件,并指定防盗链规则.

如何指定,分析referer,如果不是来自本站,从写url.

重写规则

那种情况重写:

是jpeg/jpg/git/png图片时.
是referer头信息与localhost不匹配时重写.

> 如何重写

统一rewirte 到 某个防盗链图片.

mod_rewrite

.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, "

"), 4));
http协议缓存控制

图片的下载:
第一次请求 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 " [plus] { }*"
ExpiresByType type/encoding " [plus] { }>*"

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


header set Cache-Control: "no-store,must-revalidate"
http内容压缩

为了提高网页在网络上的传输速度.服务器对主体信息进行压缩.
常见的,gzip压缩,deflate压缩,compress压缩以及sdch压缩.

压缩的过程:

服务器返回压缩内容,客户端接收到压缩,再解压缩,再渲染页面.
Content-Length压缩后的长度

实际渲染的文件大小:

如何在apache启用的压缩功能?

开启deflate模块,或者gzip模块

LoadModule deflate_module modules/mod_deflate.so

conf文件中,配置:


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

为什么要指定文件类型压缩.

压缩需要耗CUP资源

图片/视频等文件,压缩效果不好.

一般指定压缩文本格式的文件.

服务器如何知道浏览器支持gzip压缩

客户端允许发送Accept-Encoding信息.与服务器协商.(协商头信息)

comet方向ajax

http协议+持久连接+分块传输 => 反向ajax
反向ajax又叫:comet,server push,服务器推技术.

应用范围:网页聊天服务器,新浪微博在线聊天,google mail网页聊天.

原理:HTTP协议的特点,连接--断开.

具体什么时间断开?
服务器响应content-length,收到指定length长度的内容时,也就断开.

在http1.1协议中,允许不写content-length。(比如要发送的内容长度确实不知道)这是,需要一个特殊的content-typechunked

分块传输:

";
    ob_flush();
    flush(); // 把产生的内容立即返回给浏览器,而不要等待浏览器结束
     
     
    $i = 1;
    while ( $i++ ) {
        echo $pad, "
"; echo $i, "
"; ob_flush(); flush(); sleep(1); } /** * * 即时通信. * * 服务器端不间断,推送信息. 到客户端. */ ?>

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22162.html

相关文章

  • php中curl和soap方式请求服务超时问题

    摘要:公司中有不少服务是以或者方式连接第三方公司做的服务来交互数据,最近新增加了个需求,就是第三方服务发版时候,连接不上对方服务器时候要进行重试,其它原因导致的业务处理失败,则按失败处理,不会再进行调用。 公司中有不少服务是以curl或者soap方式连接第三方公司做的服务来交互数据,最近新增加了个需求,就是第三方服务发版时候,连接不上对方服务器时候要进行重试,其它原因导致的业务处理失败,则按...

    Apollo 评论0 收藏0
  • 鹅厂干货 | 腾讯游戏APP协议迭代的那些事

    摘要:本文则主要总结了心悦俱乐部的接入层从文本协议到二进制协议迭代过程中的技术方案,包括协议规范安全性等方面的内容。在心悦的文本协议方案中,采用的是对请求数据进行模式的加密。包括明文的协议包头和密文的二进制流。 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~。 作者:罗广镇 | 腾讯移动开发工程师 App与后台通信通常有采用json等文本协议或者采用二进制协议,本文则主要总结了心...

    luck 评论0 收藏0
  • 网络基础(一)

    摘要:数据链路层中的主要协议有点对点协议协议以太网。协议是网际层的核心通过路由选择将下一跳封装后交给网络接口层。用来检测网络是否通畅使用命令。开放表明协议不是受某一家厂商控制而是公开发表的。 博文参考 http://www.cnblogs.com/gsk99/p/4920699.html http://www.cnblogs.com/iloverain/p/5619665.html http...

    smallStone 评论0 收藏0

发表评论

0条评论

ziwenxie

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<