美文网首页
HTTP各种特性及部分跨域知识

HTTP各种特性及部分跨域知识

作者: 没了提心吊胆的稗子 | 来源:发表于2019-08-15 10:05 被阅读0次

    CORS跨域
    用node创建两个server

    // server.js
    const http = require('http');
    const fs = require('fs');
    
    http.createServer(function (request, response) {
        console.log('request comes ', request.url);
        const html = fs.readFileSync('test.html', 'utf8');
        response.writeHead(200, {
            'Content-Type': 'text/html'
        });
        response.end(html);
    }).listen(8888);
    
    // server2.js
    const http = require('http');
    http.createServer(function (request, response) {
        console.log('request comes ', request.url);
        response.writeHead(200, {
            'Access-Control-Allow-Origin': '*'
        });
        response.end('123');
    }).listen(8887);
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <script>
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://127.0.0.1:8887/');
        xhr.send();
    </script>
    </body>
    </html>
    

    请求已经发送,内容也返回了,只是浏览器在解析的时候发现没有设置Access-Control-Allow-Origin,就会自动拦截返回的内容

    JSONP,即使server2.js不设置Access-Control-Allow-Origin也是可以成功的。利用了script,link,img等标签不受跨域限制的原理

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <script src="http://127.0.0.1:8887/"></script>
    </body>
    </html>
    

    允许的方法:GET,HEAD,POST
    允许的Content-Type:text/plain,mutilpart/form-data,application/x-www-form-urlencoded
    CORS限制
    1、预请求,除了允许的几个不需要,其他都需要进行预请求
    2、其他限制:
    请求头限制,
    XMLHTTPRequestUpload对象均没有注册任何事件监听器,
    请求中没有使用ReadableStream对象
    解决:可以设置允许的请求头
    'Access-Control-Allow-Headers': 'X-Test-Cors'
    同理:其他方法的限制也可以通过这种方式设置
    'Access-Control-Max-Age': '1000'这种方式告诉浏览器在1秒之内不再预请求

    可缓存性Cache-Control
    属性值:
    public:客户端向服务器发送请求,经过的代理服务器等所有的都可以进行内容的缓存
    private:只有发起请求的客户端可以进行缓存
    no-cache:可以缓存,但每次请求都要发送到服务器端确认是否可以使用缓存
    no-store:不可以缓存,每次都要去服务器端拿新的内容过来使用

    到期
    max-age = <seconds>:缓存的过期时间 (浏览器端)
    s-maxage = <seconds>: 主要是给代理服务器设置的
    max-stale = <seconds>:发起请求的一方带过去的,即使缓存过期了只要有这个属性设置的时间内,就还可以使用过期的缓存(浏览器中用不到)

    重新验证
    must-revalidate:如果设置了max-age并且缓存过期了,那么浏览器端就必须再次发起请求去服务器端获取数据,验证缓存的内容是否真的过期,不能直接使用过期的缓存
    proxy-revalidate:用于代理服务器

    // 设置缓存
    response.writeHead(200, {
                'Content-Type': 'text/javascript',
                'Cache-Control': 'max-age=2000'
            });
    

    浏览器发送请求查看缓存的过程


    Last-Modified:上次修改时间
    配合If-Modified-Since或者If-Unmodified-Since使用,一般都是前者
    If-Modified-Since可以在下次请求的时候带去服务器对比资源上次修改时间,如果相同说明资源没被修改过,服务器就告诉浏览器(返回304状态码)可以直接使用缓存,此时服务器不会再返回If-Modified-Since值,因为没有变化。如果不一样Last-Modified会被更新,下次再请求时浏览器带过来的If-Modified-Since值就是这个Last-Modified
    Etag:签名,服务器生成的每个资源的唯一标识,只要有修改,该值就会有变化(典型案例就是对资源的URL进行一个hash的计算)
    配合If-Match或者If-None-Match使用
    过程同上,不一样的是,即使返回状态码304,也会再次生成一个新的Etag返回给浏览器
    对比
    两者都是协商缓存,优先验证Etag
    对于频繁修改的文件,前者只能检查到秒级
    文件有时会定时重新生成相同内容,Last-Modified不能很好辨别
    Etag每次服务端生成都需要进行读写操作,而Last-Modified只需要读取操作,Etag的消耗是更大的

    Cookie
    Cookie是服务器端返回数据通过Set-Cookie设置把一些内容保存到浏览器,不能跨域设置
    浏览器下次请求的时候会自动带上,
    键值对的形式
    max-ageexpires过期时间,同时存在的话以前者为准,两者区别在于前者是相对于客户端的时间,后者是相对于服务器的绝对时间,可能会出现稍微的偏差
    Secure只在HTTPS的时候发送
    HTTPOnly设置之后表示无法通过document.cookie修改存储的Cookie
    多个Cookie用数组表示

    Session
    最常用的方法是使用Cookie保存Session,不一样的是Session是在服务器端,例如用户登录,每一个用户登录保存登录名密码在cookie中之后会有一个唯一的id存放在服务器端,这个id就是sessionId,下次再登录的时候拿到登录用户的id去跟sessionId对比。

    HTTP长连接,也叫持久连接
    HTTP请求的过程中要先建立一个TCP连接,在TCP连接的基础上进行HTTP的请求与接收等一系列交互,一次HTTP请求结束,如果立刻关闭TCP连接(短连接),就可以减少一直连接的消耗;但若是很快又会有请求,那么又需要进行三次握手的过程,就会有网络延迟的开销。如果一直开着(长连接),下次请求就可以直接在这个连接上请求发送。
    一般情况下,网站的并发量都很大,如果每次都去重新创建TCP连接,开销可能远远超过一直开着连接的消耗,因次用长连接是一种比较好的解决方案,长连接可以设置timeout,在一定时间内没有请求发送就自动断开。
    'connection': 'Keep-Alive'
    因为对请求的处理都是串行的,要按照请求的先后顺序,因此一般网站都是先开6个HTTP请求,等到前六个加载完后面再等待
    而在HTTP2.0里面实现了请求的并行处理,只需要开一个HTTP连接就可以实现并行
    管线化
    只有GET,HEAD可以,对POST有所限制,HTTP1.1支持,除此创建时不应启动,因为不确定对方是否支持管线化
    不安全,如果一个管道中有10个连接,在发送出9个后,突然服务器告诉你,连接关闭了,此时客户端即使收到了前9个请求的答复,也会将这9个请求的内容清空,也就是说,白忙活了……此时,客户端的这9个请求需要重新发送。这对于幂等请求还好(比如get,多发送几次都没关系,每次都是相同的结果),如果是post这样的非幂等请求(比如支付的时候,多发送几次就惨了),肯定是行不通的。所以,post请求不能通过管道的方式进行通信!

    数据协商
    表示在请求头里设置的告诉服务器都需要什么数据,数据都是什么类型的,服务端根据这些信息返回相应的数据
    请求里面通过Accept设置
    Accept:指定想获取的数据类型
    Accept-Encoding:数据的编码格式,服务端主要靠这个来决定使用哪种编码方式
    Accept-Language:返回的语言
    User-Agent:可以用来区分是PC端的页面还是移动端的页面


    服务端返回设置Content
    Content-Type:对应AcceptAccept里面可以设置好几种不同的数据格式,服务端选择一种来返回,通过Content-Type告知服务端
    Content-Encoding:编码方式
    Content-Language:语言
    'X-Content-Type-Options': 'mosniff':有的请求没有表明请求的数据类型,服务器端就会预测这个类型,可能会造成安全隐患,这个设置可以防止预测

    301/302重定向
    两个的区别是
    301:是永久重定向,第一次服务器设置完重定向页面之后会把这个路径保存在缓存里面,后面再次请求就不需要经过服务器继续设置了,基本上没有过期时间,尽可能长时间的缓存
    302:是临时重定向,每次访问的时候都需要服务器来指定跳转的页面

    Content-Security-Policy(CSP)内容安全策略
    作用:
    限制资源获取:从哪里获取,请求发到哪个地方等都可以限制
    限制方式:
    default-src限制全局资源的请求范围,指定特定的资源类型


    设置只能通过http/https的方式加载,不能直接在网页里面加载 ,外联的script是可以执行的。
    还可以设置只能加载本域名下的脚本文件
    'Content-Security-Policy': ' default-src \'self\' '要用引号引起来
    设置表单提交只能提交到本站有另外的方式
    'Content-Security-Policy': ' default-src \'self\'; form-action \'self\' '
    default-src是限制所有类型,但各类型的限制可以如上图设置
    还可以设置指定的网站

    <div>
        <div>this is content</div>
    </div>
    
    <script>
        console.log('inline js');
    </script>
    <script src="/test.js"></script>
    

    报告资源获取权:向服务器报告一些没有预知到的情况以便做出一些调整
    'Content-Security-Policy': ' default-src \'self\'; form-action \'self\'; report-uri /report '
    report-uri /report指定服务器的报告路径
    'Content-Security-Policy-Report-Only': ' default-src 'self'; form-action 'self'; report-uri /report '
    只报告但是不做限制
    每一个限制的内容都会发一个report请求
    除了在header中设置限制,还可以通过html页面中的meta标签设置,但是不能报告,报告只能在header里面设置

    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; form-action 'self';">
    

    相关文章

      网友评论

          本文标题:HTTP各种特性及部分跨域知识

          本文链接:https://www.haomeiwen.com/subject/voqnjctx.html