HTTP协议2

034.HTML与表单
    HTML: HyperText Markup Language, 结构化标记语言(非变编程语言),浏览器可以将HTML文件渲染为可视化网页
    FORM表单: HTML中的元素,提供了交互控件来向服务器通过HTTP协议提交信息,常见的空间有
        Text Input Controls: 文本输入控件
        Checkboxes Controls: 复选框控件
        Radio Box Controls: 单选框控件
        Select Box Controls: 下拉框控件
        File Select Controls: 文件选择控件
        Clickable Button Controls: 按钮控件
        Submit and Reset Button: 提交或者重置按钮控件,
        其中submit用于直接发起http请求
        HTML FORM 表单提交请求时的关键属性
            action: 提交时发起HTTP请求的URI
            method: 提交时发起HTTP请求的HTTP方法
                get: 通过URI,将表单数据以URI参数的方式提交
                post: 将表单数据放在请求包体中提交
            enctype: 在POST方法下,指定表单内容在请求包体中的编码方式
                .application/x-www-form-urlencoded 
                 数据被编码成以&分割的键值对,同时以=分割建和值,字符以URI编码方式编码
                .multipart/form-data 包含两部分,第一部分是一个或多个资源表述,第二部分是last boundary(最后一个分隔符,一般以--开头,但是一定是以 -- 结尾)。
                分成多个资源表述,比如一个输入框就是一个资源表述,一个文件选择框又是一个资源表述
                每一个资源表述包含两部分 boundary(分隔符,一般以--开头)和 body-part(包体)
                其中包体又必须包含两个头部
                content-disposition: form data; name="XXX"; fileName="1.txt" 这里的name就是<input 标签的name/>
                content-type: 表示包体的类型,例如是文字,图片,还是其他的
        <html>
        <body>

        <p>POST方法默认提交</p> 等同于application/x-www-form-urlencoded
        <form action="/sendhttpreq" method="post">
            <p>姓名: <input type="text" name="name" style="width: 300px" /></p>
            <p>性别: <input type="radio" name="sex" value="male" checked>男
            <input type="radio" name="sex" value="female">女</p>
        <p><input type="submit" value="提交" /></p>
        </form>

        <p>GET方法默认提交</p>
        <form action="/sendhttpreq" method="get">
            <p>姓名: <input type="text" name="name" style="width: 300px" /></p>
            <p>性别: <input type="radio" name="sex" value="male" checked>男
            <input type="radio" name="sex" value="female">女</p>
            <p><input type="submit" value="提交" /></p>
        </form>

        <p>POST方法以application/x-www-form-urlencoded编码方式提交</p>
        <form action="/sendhttpreq" method="post" enctype="application/x-www-form-urlencoded">
            <p>姓名: <input type="text" name="name" style="width: 300px" /></p>
            <p>性别: <input type="radio" name="sex" value="male" checked>男
            <input type="radio" name="sex" value="female">女</p>
            <p><input type="submit" value="提交" /></p>
        </form>

        <p>POST方法以multipart/form-data编码方式提交,且上传文件</p>
        <form action="/sendhttpreq" method="post" enctype="multipart/form-data">
            <p>姓名: <input type="text" name="name" style="width: 300px" /></p>
            <p>性别: <input type="radio" name="sex" value="male" checked>男
            <input type="radio" name="sex" value="female">女</p>
            <p>要上传的文件1<input type="file" name="file1"/></p>
            <p>要上传的文件2<input type="file" name="file2"/></p>
            <p><input type="submit" value="提交" /></p>
        </form>
        </body>
        </html>

035.Rang请求,多线程并发下载、断线续传、随机点播等场景
    多线程并发下载、断点续传、随机点播等场景的步骤
    1.客户端明确任务,从哪下载
      本地是否已有部分文件
      文件已经下载的部分在服务器端是否已经发生了改变
      使用几个线程并发下载(迅雷)
    2.下载文件制定部分的内容
    3.下载完毕后封装成统一的文件
    HTTP Range规范(RFC7233)
    允许服务器基于客户端的请求只发送相应包体的一部分到客户端,而客户端自动将多个片段的包体组合成完整的内容,支持断点续传、支持多线程下载、支持视频播放实时拖动
    服务器端通过Accept-Ranges头部来告知客户端是否支持Range请求,Accept-Ranges: bytes 表示支持基于字节流的Range请求,Accept-Ranges: none 表示不支持range请求
    基于字节的range请求范围单位,假设包体的总长度为10000字节
    第1个500字节: Range: bytes=0-499
    第2个500字节:Range: bytes=500-999
                  Range: bytes=500-600,601-999
                  Range: bytes=500-700,601-999
    最后500字节:Range: bytes=-500
                 Range: bytes=9500-
    只需要第一个字节和最后一个字节 bytes=0-0,-1
    Range条件请求
    如果客户端已经得到了Range响应的一部分,并想在这部分响应未过期的情况下,获取其他部分的响应
    常与If-Unmodified-Since或者If-Match头部共同使用
    If-Range = entity-tag / HTTP-date  etag 和date 是由服务器生成的
    可以使用Etag或者Last-Modified 
    例如 curl protocal.taohui.tech/app/letter.txt -H 'Range: bytes=6-10' -H 'If-Match:"5cc3f0b5-1b"'  如果服务器发现条件不匹配就会返回 412 Precondition Failed
    使用range请求时,服务器端如果成功返回了range请求的请求内容,返回码并不是200 OK而是 206 Partial Content 并包含一个Content-Range头部 例如 Content-Range: bytes 42-1233/1234 或者 Content-Range: bytes 42-1233/*
    如果请求的范围是不对时,比如资源长度只有26 但是我们请求 Range: bytes=30-40 这时服务器就会返回 416 Range Not Satisfiable 并返回包体的长度头部Content-Range: byte */1234
    如果服务器端不支持Range请求时,直接返回200 OK 将完成的包体发送给客户端
    如果采用多段的形式例如: Range: bytes=0-5,10-19 时服务器端就会使用Content-Type: multipart/byteranges; boundary=0000000000000000000000000096告知客户端由这个响应包含多个包体,每个包体使用分隔符0000000000000000000000000096分割
    例如执行 curl protocal.taohui.tech/app/letter.txt -H 'Range: 0-5, 10-15'  返回的结果如下:
    --0000000000000000006097
    Content-type: text/plain; charset=utf-8
    Content-Range: bytes 0-5/26
    
    abcdef
    --0000000000000000006097
    Content-type: text/plain; charset=utf-8
    Content-Range: bytes 0-5/26
    
    klmnop
    --0000000000000000006097--
036. Cookie 
     保存在客户端的,由浏览器维护的
     是由服务器端生成的
     它可以存放在内存或磁盘中,
     服务器通过 Set-Cookie: key=value 来将Cookie发送给客户端的,
     客户端得到cookie后保存在缓存中,在后续针对同一域名下的所有请求,都会带上cookie: key=value 请求头
     cookie的描述cookie-av
        -expire Expire=snae-cookie-date 表示cookie到日期snae-cookie-date时失效
        -max-age Max-Age=non-zero-digit cookie 经过non-zero-digit秒后失效 优先级高于Expire
        -domain Domain=domain-value 指定cookie可以用于哪些域名,默认可以访问当前域名
        -path Path=path-value 指定访问Path路径时才能使用该cookie
        -secure Secure 只有使用TLS/SSL协议(https)时才能使用cookie
        -httponly HttpOnly 不能使用JavaScript(Document.cookie,XHLHttpRequest,Request APIs) 访问到cookie
    例如 Set-Cookie: key=value; path=/xxx; HttpOnly
    RFC规范浏览器对cookie的要求
     每条cookie的长度至少要达到4K以上
     每个域名下至少支持50个cookie
     至少要支持3000个cookie同时存在
     代理服务器传递cookie时会有限制
037.cookie与session
    常见登录
    1.Client POST/login
    2.Server 比对数据库
    3.Server 将有失效的登录状态写入数据或者缓存
    4.Server 返回 200 OK Set-Cookie: session-id=xxx;max-age=3600
    5.Client GET/data Cookie:session-id=xxx
    6.Server 获取的session-id后去数据库或缓存查找对应的session-id对应的登录状态,发现是已登录的
    7.Server执行业务逻辑后返回200 OK
038.无状态的REST架构与状态管理
    .应用状态与资源状态
        .应用状态:应该由客户端管理,不应该由服务器管理,例如浏览器目前处于应用的哪一个页面,
        .资源状态:应该由服务器管理,不应该就客户端管理,例如数据库中存储的数据状态,例如用户的登录状态等
    .HTTP请求的状态
        .有状态的请求:服务器端保存请求的相关信息,每个请求可以使用以前保留的相关信息,例如服务器端使用session机制保存请求的相关信息,后续的请求中只要使用cookie携带查询信息,
                       与session配合完成有状态的请求,例如根据用户查询用户的购物车列表就是一个有状态的请求
        .无状态请求: 服务器能处理的所有信息都来自当前请求所携带的信息,例如获取一个JS库文件,就是一个无状态请求
039.第三方Cookie
    第三方Cookie的作用一般是用户收集用户的浏览信息,例如用户在A购物网站浏览过商品AAA后,再去浏览B购物网站,这时B网站就知道用户在A网站过浏览过商品AAA,这时它就可以给用户推荐一些AAA类的商品,这就是第三方Cookie的作用
    浏览器允许对于不安全域(跨域)下的资源(如广告图片)响应中的Set-Cookie保存,并在后续访问改域名时自动使用Cookie,例如A网站的页面中使用了B网站的一张图片(img标签的src是第三方的URI),同时浏览器允许网站B在返回
    这个图片的请求里携带新的cookie,这样当用户在同一个浏览器客户端中去直接访问站点B时就会携带上这个cookie,这时站点B就知道这个用户在A站点浏览过对应的页面(站点B把cookie设置成:Set-Cookie: sitename:A这样)
040.同源策略
    面临的问题
    用户在浏览器里访问银行站点A登录后,站点A在响应头中会通过Set-Cookie将session-id返回给浏览器,下次用户再访问登录后的请求时就会使用Cookie头部带上这个session-id
    假如这时用户在已经登录了站点A的情况下通过某些广告的诱导又打开另外一个标签页,在这个标签页里浏览恶意站点B,这时恶意站点B就会尝试获取站点A的当前页面的DOM结构,并且通过脚本将DOM元素的值给改成自己希望的值,例如银行账号
    改了DOM结构之后再使用JS向站点A的请求,这时浏览器自动就将之前站点A返回的session-id以cookie头部的形式发送给站点A,从而导致盗刷银行卡的悲剧
    同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源进行交互
    同源就是:协议,主机,端口必须一样
    同源策略就是要找到一个可用性和安全性的平衡点
    可用性:HTML的创作者决定跨域请求是否对本站点安全, 例如img标签的src属性的URI路径就是由程序开发者指定的, 再比如允许跨域的写操作,例如表单提交或者重定向请求,CSRF安全问题
    安全性:浏览器要防止其他站点向本站点发起危险动作。
            Cookie,LocalStorage,和IndexDB不让其他站点读取
            DOM不允许其他站点获取
            允许其他站点发送AJAX请求等
    CSRF (Cross-Site Request Forgery)跨站请求伪造攻击
        跟上面的例子类似,就是用户在已经登录了站点A的情况下,又去访问站点B,站点B伪造了一个和A很像的页面,这个页面包含一个form表单,但是form表单的action是站点A的接口URI,这是用户以为浏览的是站点A,用户点击伪造页面的按钮
        触发form表单的submit,这时就会像A站点服务器发起HTTP请求,并携带上之前用户登录站点A时获得的cookie(session-id),从而造成非常严重的后果
    防止CSRF的方法很简单,一般浏览器都会在发送的HTTP请求中放一个Referer头部标明这个请求来自哪个域名,这时服务器在收到请求后判断Referer就知道来自哪些域名的请求该拒绝执行了,但是有些浏览器不遵循RFC的这种规范,就不带Referer头部
    为了彻底解决CSRF最早期的解决办法是用户在登录时,服务器端随机生成一个sessionid,并通过包体,而不是头部返回给客户端,客户端在拿到这个sessionid后在form表单里用一个隐藏的字段存放这个sessionid,然后在submit后将sessionid发给后端验证
    这样木马站点就无法伪造这个form表单了,这样做也比较麻烦,就是每次都要去构造这个隐藏的文本域
    现在更流行的做法是使用SessionStorage,SessionStorage是浏览器为每一个域设置的独有字段,来自其他域的JS脚本是无法读取里面的内容的,就是将sessionid放入到SessionStorage里面。
041.浏览器同源策略下的跨域访问解决方案
    如果站点A允许站点B的脚本访问其资源,必须在HTTP响应中显示地告知浏览器:站点B是被允许访问的
       。访问站点A的请求,浏览器应该告知请求来自站点B
       。站点A的响应中,应该明确告知哪些跨域请求是被允许的
    简单请求的跨域访问,同时满足下面三个条件才能算一个简单请求
       。GET/HEAD/POST 方法之一
       。仅能使用CORS安全的头部:Accept、Accept-Language、Content-Language、Content-Type
       。Content-Type的值只能是: text/plain、muitlpart/form-data、application/x-www-urlencoded三者之一
        向服务器发送HTTP请求时,客户端可以携带Origin头部,来告知这个请求来自哪个域,而客户端在响应中必须使用头部Access-Control-Allow-Origin: 来告知客户端服务器允许哪些域访问 这就是针对简单请求的跨域访问策略
        No 'Access-Control-Allow-Origin' header is present on the requested resource. 产生这个错误的原因是在站点A(http://www.AAAAA.com)的页面中,使用JS或者form表单去向站点B(http://www.BBBB.com)的服务器发起HTTP请求,
        跨域访问的时候都会默认携带上Origin: http://propocal.taohui.tech 这个头部,这时站点B不允许 http://www.AAAAA.com访问,这时它就成功返回一个200 OK的响应给浏览器,但是这时的响应头部里面并不包含Access-Control-Allow-Origin这个头部
        这时,浏览器接受到响应后发现响应里没有Access-Control-Allow-Origin这个头部,就使用console输出Access-Control-Allow-Origin。当响应中有这个头部,但是这个头部的值不是 http://www.AAAAA.com或者* 这时就会报 'Access-Control-Allow-Origin'
        Not equal
    复杂请求的的跨域访问
        复杂请求的跨域访问分成两个步骤,首先要进行预检请求,然后再发起真正的业务逻辑请求
        预检请求的头部(预检请求一般都是OPTIONS方法)
        Access-Control-Request-Method: 表示后面真正的请求的方法
        Access-Control-Request-Headers: 表示后面的请求我要传哪些头部
        预检请求响应
        Access-Control-Allow-Methods: 告知浏览器支持哪些方法
        Access-Control-Allow-Headers: 告知浏览器允许传哪些头部
        Access-Control-Max-Age: 允许缓存的最长时间
        Access-Control-Expose-Headers: 告知浏览器哪些响应头部可以提供客户端使用,默认情况下只有Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma可供使用
        Access-Control-Allow-Origin: 告知浏览器允许哪些域来访问当前站点的资源, *表示所有的域,为避免缓存错乱,响应中需要携带Vary: Origin头部
            因为一个域名下可以发起多个ajax请求,ajax请求的响应是可以被缓存的,响应中就必修携带Vary: Origin以使得我们的缓存能够区分出来来自不同的域。
        Access-Control-Allow-Credentials:告知浏览器是否可以将Credentials暴露给客户端使用,Credentials包含cookie和authorization头部、TLS证书等
042.条件请求
    条件请求的作用:
    。是缓存的更新更有效率(如浏览器的缓存已经过期了,发起一个请求去获取新的资源,但是服务器端的资源并没有改变就返回304响应码是服务器不用传递包体,让浏览器继续使用过期的缓存,从而减少带宽和响应速度)
    。断点续传时对之前的内容进行验证
    。当多个客户端并行修改统一资源时,防止某一客户端的更新被错误的丢弃
    条件请求的执行过程是:
    客户端在请求中携带验证信息,服务器对资源进行预验证客户端传过来的验证信息是否满足,如果满足则不返回包体,如果不满足则重新返回包体
    etag相应头部
    强验证器:ETage: "xyz"
    弱验证器:ETage: W/"xyz"
    Last-Modified 相应头部,表示对应资源表述的上次修改时间
    Date头部: 表示响应包体的生成时间  Last-Modified不能晚于Date
    
    条件请求头部:
    If-Match: "entity-tage" 如果匹配了就返回客户端请求的包体,如果不匹配则返回412
    If-None-Match: "entity-tage" 如果不匹配则返回客户端请求的包体,如果匹配了就返回304
    If-Modified-Since : HTTP-date 如果从HTTP-dat开始到现在资源被修改过则返回完整包体,如果没有被修改过则返回304
    If-Unmodified-Since : HTTP-date 如果从HTTP-dat开始到现在资源没有被修改过则返回客户端请求的包体,否则返回412
    If-Range: entity-tage / HTTP-date
    典型的应用场景(-)缓存更新
    1.客户端首次请求,客户端返回完整的包体并携带Last-Modified: date1 和 Etag: "xyz1"
    2.客户端的缓存过期啦,这时再起发起请求携带上If-Modified-Since: date1 和 If-None-Match: "xyz1" 这两个头部发送给服务器,
    3.服务器执行If-Modified-Since和If-None-Match这两个验证器,如果资源没有被改过,则返回304告诉客户端让它继续使用过期的缓存
    4.如果.服务器执行If-Modified-Since和If-None-Match这两个验证器,发现资源已经被改过了,于是返回完整包体,并携带Last-Modified: date2 和 Etag: "xyz2" 让浏览器在下一次缓存过期时使用
    典型的应用场景(二)增量更新
    1.客户端首次请求资源的一部分,服务器端返回请求的那一部分资源并携带上Etage:"xyz1" 和 Last-Modified: date1 
    2.客户端再次请求其他部分的包体,携带上If-Unmodified-Sice: date1 和 If-Match: "xyz1" ,服务器执行预验证,如果验证通过就返回客户端请求的那部分包体,如果验证通过则返回412
    3.如果客户端收到了412,则从新发起一个第1步的请求
    典型的应用场景(三)防止修改被错误的丢弃,乐观锁
    客户端1和客户端2同时对一个服务器上的资源进行修改
    1.客户端1发起get请求首次获得了资源,这时响应头包含了Last-Modified: date1 和 Etag: "xyz1"
    2.客户端2发起get请求首次获得了资源,这时响应头包含了Last-Modified: date1 和 Etag: "xyz1"
    3.客户端1首先修改完,发起PUT请求,携带If-Match: "xyz1" 和 If-Unmodified-Since: date1 ,这时客户端验证,由于资源没有修改过,所以验证通过,执行客户端1的PUT请求
    4.客户端2修改完了,发情期PUT请求,携带If-Match: "xyz1" 和 If-Unmodified-Since: date1 ,这时客户端验证,由于资源已经被修改过(Last-Modified变成了date2,Etag变成了xyz2),所以验证不通过,返回412 Precondition Faild
    5.客户端2重新获取资源
043.缓存
    私有缓存 仅供一个用户使用的缓存,一般存放在客户端 
    共享缓存 可以提供给多个客户端使用,一般都存放在代理服务器上(例如热点资源经常存储在代理服务器上减轻源服务器的压力并提升网络效率)。Authentation响应不能被代理服务器缓存
    缓存的存在形式是key-value的形式,key是由schema、path和host构成,例如:http://path1Host1
    value则是一个LRU双向链表,即每一个key指向双向链表中的某一个value
    判断缓存是否过期有一个复杂的计算过程 s-maxage > max-age > Expire > 预估过期时间
    Age头部,表示自源服务器发出响应,到使用这个缓存的响应发出时经过的秒数
    Cache-Control头部
    请求中的头部
    max-age max-age=100 告诉服务器,客户端不会接受Age超出max-age秒的缓存
    max-stale max-stale=100 告诉服务器,即使缓存不再新鲜,但是陈旧描述没有超过max-stale时,客户端任然打算使用,如果max-stale后没有=和值,表示可以永久使用
    min-fresh min-fresh=100 告诉服务器, Age至少经过min-fresh秒后缓存才可使用
    no-chache no-chache 告诉服务器不能使用已有缓存作为响应返回,除非带着缓存条件到源服务器得到304响应码才可以使用现有缓存
    no-store no-store 告诉代理服务器不要对该请求的响应进行缓存
    no-transform no-transform 告诉代理服务器不要修改本请求的响应的包体
    only-if-cached only-if-cached 告诉服务器仅使用缓存作为响应,不要去源服务器请求,若没有缓存则返回504错误码
    响应中的头部
    max-age  max-age=100  告诉客户端缓存Age超过max-age秒后则缓存过期
    s-maxage s-maxage=100 与max-age类似,但是仅针对共享缓存,且优先级高于max-age和Expire
    must-revalidate must-revalidate 告诉客户端一旦缓存过期,必须向服务器验证后才可使用
    proxy-revalidate  proxy-revalidate 与must类似,但它仅对代理服务器的共享缓存有效
    no-cache  no-cache或者no-cache= 第一种用法告诉客户端不能直接使用缓存的响应,使用前应在源服务器验证得到304返回码,用法二:如果包含指定的头部,若客户端的后续请求以及响应中不含有这些头部,则可以直接使用缓存
    no-store  no-store 告诉所有的下游节点不能对响应进行缓存
    no-transfer no-transfer 告诉代理服务器不能修改包体的内容
    public public 表示无论是私有缓存还是共享缓存,都可以将该响应缓存
    private private private或者private= 表示该响应不能被代理服务器作为共享缓存使用,若private后制定头部,则在告诉代理服务器不能缓存指定的头部,但可以缓存其他部分。
    什么样的请求响应会被缓存
    。并不是只有GET请求才能被缓存
    。响应码要能让缓存理解
    。响应与请求头部没有指明no-sorte
    。响应中应含有以下头部中的1个或者多个:Expires, max-age, s-maxage, public 当响应中没有明确指明过期时间,但是响应码非常明确,也可以被缓存
    。如果缓存在代理服务器上,不能含有private头部和Authorization头部
    。Pragram: no-cache 与Cache-Control: no-cache 意义相同
    使用缓存作为当前请求的响应的条件
    。URI是匹配的,URI作为最主要的缓存关键字,当一个URI对应多份缓存时,选择日期最近的缓存作为响应
    。缓存中的响应允许当前请求的方法使用缓存
    使用缓存作为当前请求响应的条件
    。缓存中的响应Vary头部指定的头部必须与请求中的头部相匹配 Vary: * 意味着一定匹配失败
    。当请求和缓存中的响应都不包含no-cache头部
    。缓存中的响应必须是以下三者之一
        A。未过期的
        B。缓存中的响应头部明确告知可以使用过期的缓存
        C。使用条件请求去服务器端验证请求是否过期,得到304响应码
044.重定向
    重定向解决的问题
    。提交FORM表单成功后需要显示新的内容页
    。站点从http迁移到https    
    。站点部分URI发生了变化,但是搜索引擎或者流量入口站点只收录了老的URI
    。站点正在维护中,需要给用户展示不一样的内容
    。站点更换了域名等
    重定向的流程
    1.客户端 GET
    2.客户端返回 3xx 和一个Location头部,客户端接收到响应后需要跳转到Location头部指定的新的URI
    永久重定向响应返回码,永久重定向是可以被缓存的
    原请求:接收到重定向响应码的请求称为原请求
    重定向请求:浏览器在接收到重定向响应码后,会发起新的重定向请求(跳转到新的页面就需要发起一个获取HTML页面的请求)
    301 重定向请求会使用GET方法,而不管原请求是什么方法
    308 重定向请求必须使用元请求的方法和包体发送请求
    临时重定向,表示资源只是临时的变更
    302 重定向请求通常会使用GET方法,而不管原请求是什么方法
    303 它并不表示资源变迁,而是用新的URI的响应表述为原请求服务,重定向请求会使用GET方法。,例如表单提交后向用户返回新内容
    307 重定向请求必须使用原请求的方法和包体发起访问
    特殊的重定向
    300 响应式内容协商中,告知客户端有多种资源表述,要求客户端选择一种自认为合适的表述
    304 服务器端验证过期缓存有效后,要求客户端使用该缓存
    重定向会产生循环,例如访问URI1时,服务器返回重定向到URI2,访问URI2时服务器返回重定向到URI1,这样一直循环,浏览器就会报错:ERR_TOO_MANY_REDIRECTS
045.Tunnel隧道
    用于通过HTTP连接传输非HTTP协议格式的消息,常用于穿越防火墙,建立隧道后,由于传输的不是HTTP消息,因此不再遵循请求、响应模式,已变为双向传输
    。用于防火墙拒绝SSL流量时穿越防火墙
    。用于代理服务器没有证书,让代理服务器能够正常转发SSL流量
047.网络爬虫
    网络爬虫是模拟人类使用浏览器浏览,操作页面的行,对互联网站点进行操作
    网络爬虫捕获到一个URI页面后,会分析出页面里所有的URI,并沿着这些URI递归的遍历所有页面,因此被称为爬虫
    比如百度搜索爬虫的工作原理是,BaiduSpider会爬取全网的站点,把这些站点爬取下来存放在自己的搜索库里,当用户在百度中输入相应的关键字之后,就从这些搜索库里取出相应的页面展示给用户
    对待爬虫有两种态度
    允许爬虫访问爬取自己的站点
    。“合法的优化” sitemap title keywords https等
    。“非法”的优化 利用PageRank算法的漏洞
    PageRank 算法就是网页之间都是互相访问的, 被访问的最多的站点就是我们要找的目标站点(例如,在百度搜索的时候展示在最前面那个,可能就是通过PageRank算法得出来的)
    但是PageRank有一个漏洞,就是商家会制造一个访问量非常大的站点比如百度,然后商家就跟百度的客户说,你给我钱,我给你伪造许多僵尸页面来指向你的页面,从而使得你的页面在百度搜索中比较靠前
    拒绝访问爬虫的网站
    比如机票网站,火车票网站等,很多黄牛就是使用网络爬虫来爬取这些网站,发现有特价机票的时候就立马买下来,卖给普通人
    现在很多网站都使用验证码,或者图形验证码这些来对抗网络爬虫
    深度优先和广度优先
    深度优先就是沿着URI的每一条线都遍历完了,然后再去找最感兴趣的页面,它可以复用长连接,因为减少了TCP的三次握手和四次握手次数,可以解决TCP的网络拥塞,也解决了网络消耗
    广度优先就是先去爬取那些比较重要的页面,比如二级页面,然后再选择某一些线路进行深度爬取
    爬虫常见的头部
    User-Agent: 识别是哪类爬虫
    From: 提供爬虫机器人管理者的邮箱地址
    Accept: 告知服务器爬虫对哪些资源类型感兴趣
    Referer: 相当于包含了当前请求的页面的URI
    robots.txt 告知网络爬虫哪些内容不应该被爬取,或者只允许哪些爬虫爬取,或者爬取的速率
        。User-agent 允许哪些爬虫
        。Disallow 禁止访问特定的目录
        。Crawl-dely 访问间隔描述
        。Allow 抵消Disallow指令
        。Sitemap 指出站点地图的URI
    比如访问qq站点的ronots.text http://www.qq.com/robots.txt
048.HTTP协议的基本认证
    基本认证的流程
    1.客户端发送一个请求
    2.服务器返回401 Unauthorized ,并包含一个WWW-Authenticate: Basic realm="Access to the  staging site"
    3.客户端弹出输入用户名密码的页面,输入用户名密码后再次发起请求
    4.服务器验证用户信息是否正确,并处理请求

049.DNS
    什么是DNS,就是将一个域名与IP地址进行映射的数据库
    递归查询 
    域名劫持,就是传一个假的DNS服务器,然后将假的DNS服务器返回一个错误的IP地址,然后这个错误的服务器就可以对我们进行攻击了
    运营商突然会弹出一些广告,这是因为运营商的一些DNS服务器也会夹杂着把一些代理服务器的IP地址或者广告页面的IP地址发送给我们
    具体的DNS解析步骤,比如去访问http://www.example.com这个域名
    1.首先会访问一个DNS resolver 
    2.DNS resolver 会去根服务器(roo) 寻找.com的域名服务器
    3.在.com的服务器里面,又去找example.com的服务器,这时候.com的DNS服务告诉我们应该去亚马逊的DNS域名服务器里找,于是我们又去找亚马逊的DNS域名服务器
    4.最终在亚马逊的DNS域名服务器,找到了www.example.com对应的IP地址是196.456.155.111
    5.与196.456.155.111建立TCP连接并进行HTTP通讯
    DNS报文:查询与相应
    query: 查询域名
    response: 返回的IP地址
    可以使用dig工具来解析DNS的报文,DNS报文是基于UDP协议进行传输的,所以在Wireshark中使用udp就可以过滤出DNS请求

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值