HTTP基础及跨域

作者: OkGogogooo | 来源:发表于2022-06-10 15:44 被阅读0次

    1. HTTP基础

    http是HyperText Transfer Protocol 的缩写,中文称为超文本传输协议,是基于TCP/IP的一种应用层通信协议。
    一次http通信过程,可以理解为“一问一答”的过程。客户端主动发起http请求,服务端给出应答,这样就完成了一次通信。http协议本身是无状态的。举例来说,客户端C对服务端S说:“你好,我是C!”,服务端S对客户端C说,“你好C!”。这样就完成了一次http通信,下一次,C对S说:“你好,今天心情怎么样?”,S对C说:“你好,请问你是谁?”。之所以如此,是因为S并没有因为上次和C向他做过自我介绍,而记住C。即从http协议的角度来说,两次通信之间没有任何关联性,是完全独立的。但是有的人可能会说,“这不对啊,我在网页上登陆网上商城,只登陆一次就可以了,我在各个页面间跳转都知道我是谁。”这是因为当用户登陆时,服务端和客户端建立了session,或者颁发了token作为用户的身份凭据,接下来的每次http请求,都会携带sessionid或者token来告诉服务端,我是谁。这是在http协议之上约定的相互识别方法,http协议本身是无状态的。

    1.1 URL

    url,统一资源定位符。http的URL格式例子:
      http://www.example.com:80/dir/index.html?uid=1#hash2
    ● http,协议类型。
    www.example.com,服务器地址,也可以使用IP地址,必选项
    ● 80,端口号,不输入时,默认端口号,可选项
    ● dir/index.html,带层次的文件路径,指定服务器上的文件路径来定位特指的资源
    ● ?uid=1,查询字符串,可选
    ● #hash2 -> :片段标识符,hash值,可做锚点,可做前段路由,可选。在http请求时,它并不会发送到服务端。

    1.2 Http报文

    Http报文是由多行数据构成的字符串文本(ascii码,所以http叫Hyper Text Transfer Protocol)。Http报文大致可分为报文首部和报文主体两块,由空行(CR+LF)来划分。报文主体可以没有。
    请求报文结构:

    1. 报文首部
      1.1) 请求行:包含用户请求的方法,请求URI和HTTP版本。例如,GET /index.html HTTP/1.1
      1.2) 请求首部字段
      1.3) 通用首部字段
      1.4) 实体首部字段
      1.5) 其他
    2. 空行(CR + LF)
    3. 报文主体(HttpBody)
      响应报文结构:
    4. 报文首部
      1.1) 状态行:包含表明响应结果的状态码,原因短语和HTTP版本
      1.2) 响应首部字段
      1.3) 通用首部字段:
      1.4) 实体首部字段
      1.5) 其他
    5. 空行(CR + LF)
    6. 报文主体

    1.3 请求方法

    动词 REST用法 说明
    GET 获取资源 GET方法的请求不支持HttpBody传参,参数可以在URL中或者HEAD中。
    POST 新建或更新资源,以及具有较多数据需要发送到服务器,而含义更准确的动词却因无Http Body或其它原因受限的情况 POST方法的请求支持HttpBody传参。参数在URL,HEAD,HttpBody中均可。使用HttpBody时要注意设置请求的Content-Type。
    PUT 更新资源,客户端提供了完整的对象信息。
    DELETE 删除资源 DELETE请求方法是有HttpBody的,但主流框架和阿里云API网关都不支持DELETE方法的HttpBody传参。所以当通过指定多个id批量删除时,应该用POST来代替,同时URL的path中应该包含"delete"这个词(一般放在URL Path的最后)来表示这是要删除对象。这一点是不符合RESTful风格的。
    HEAD (使用较少) 存在性判定,返回布尔型的情况。 这种方式的请求的应答是没有Http Body的,主要用它的状态码。200表示对象存在,404表示对象不存在。
    OPTIONS (使用很少) 1、获取服务器支持的HTTP请求方法;2、用来检查服务器的性能。 (微服务中未见使用)
    PATCH 更新资源,客户端提供了部分发生改变的属性。
    CONNECT(使用很少) HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。要求使用隧道协议连接代理(微服务中未见使用)
    TRACE(使用很少) 回显服务器收到的请求,主要用于测试或诊断。追踪路径。(微服务中未见使用)

    1.4

    Http响应状态码是服务端对客户端请求响应的回应,它从大体上告知客户端,此次响应的类型(例如是正常、客户端请求错误,服务端出错,还是要求重定向等),以指导客户端该做出何种动作。状态码是允许自定义的,只要客户端能识别并按服务端期望进行处理即可。

    类别 信息 原因短语
    1XX Informational(信息性状态码) 接收的请求正在处理
    2XX Success(成功状态码) 请求正常处理完毕
    3XX Redirection(重定向状态码) 需要进行附加操作已完成请求
    4XX Client Error(客户端错误状态码) 服务器无法处理请求
    5XX Server Error(服务端错误状态码) 服务器处理请求出错

    1.4.1 1XX继续

    状态码 信息 表示
    100 Continue 客户端应当继续发送请求
    101 Switching Protocols 服务器已经理解了客户端的请求,并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求
    102 Processing 由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行

    1.4.2 2XX成功

    状态码 信息 表示
    200 OK 从客户端发来的请求在服务端正常处理
    204 No Content 服务端接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分,另外也不允许返回任何实体的主体
    206 Partial Content 客户端进行了范围请求, 而服务器成功执行了这部分请求,响应报文中包含由Content—Range 指定的范围的实体内容

    1.4.3 3XX 重定向

    状态码 信息 表示
    301 Moved Permanently 永久性重定向
    302 Found 临时性重定向
    303 See Other 由于对应的资源存在着另一个uri,应使用GET方法定向获取请求的资源
    304 Not Modified 客户端发送附带条件的请求,也就是资源找到了,但是没有符合条件请求
    307 Tempoeary Redirect 临时重定向,和302很相似,但是会根据游览器不同导致出现不同问题

    注意:当301、302、303响应状态码返回时,几乎所有的游览器都会把POST改为GET,并删除请求报文内的主体,之后请求会自动再次发送。301、302标准是禁止将POST改为GET方法,但实际使用时都会改变

    1.4.4 4XX 客户端错误

    4XX 的响应结果表明发生了错误,其原因来自于客户端。

    状态码 信息 表示
    400 Bad Request 请求报文中存在语法错误:游览器会像200 OK 一样对待改状态码
    401 Unauthorized 发送的请求需要通过http认证(BASIC认证、DIGEST认证)的认证信息,如果前面已经请求过一次,证明认证失败
    403 Forbidden 请求资源的访问被服务器拒绝
    404 Not Found 服务器无法找到请求的资源

    1.4.5 5XX 服务器错误

    状态码 信息 表示
    500 Internal Server Error 服务器端知悉请求时发生错误
    503 Service Unavailable 服务器暂时处于超负载或正在进行停机维护,现在无法处理请求

    1.5 常用首部字段

    • Cache-Control,通用首部字段,主要用来告知客户端、服务端或者缓存服务器,该采用何种缓存策略。
    • Date,通用首部字段,创建HTTP报文的日期时间。
    • Accept,请求首部字段,期望服务端返回的MediaType
    • Content-Length,实体首部字段,说明HttpBody的大小(字节数)。
    • Content-Type,实体首部字段,说明HttyBody的MediaType。
    • Content-MD5,实体首部字段,是HttpBody的MD5计算值。不总是设置。在http协议下,单纯依靠Content-MD5并不能防止恶意篡改HttpBody的内容,因为Content-MD5也可能被篡改。在后面的文档中,我们会提到在数字签名摘要计算过程中,把Content-MD5也加入到计算过程,可以检测出Content-MD5是否被恶意篡改,从而可以通过对HttpBody计算MD5,检测HttpBody是否被篡改。

    1.6 Cookie

      前面我们说过,http协议是无状态的。服务端为了识别当前是“谁”在访问,并可取得和“谁”相关的一个上下文,会话(session)机制就是方法之一。通常情况下,我们将会话的标识存储在cookie里面。Cookie虽然没有在http协议的RFC标准中定义,但它却是web客户端和服务端事实上都实现的机制。

      在浏览器每次发起http请求时,总是会在cookie的硬盘存储文件和浏览器进程的内存中寻找此网站域名相关的cookie,如果有且没有过期,将在Http请求的header中的Cookie字段上设置上此cookie。服务端如果支持会话和cookie,当发现客户端没有Cookie信息或者Cookie信息过期时,可以在http响应报文中附加上新的Cookie,浏览器会更新此域名相关的Cookie。

      Web服务端在收到带Cookie的http请求时,会从Cookie中提取session标识,然后从Session管理器中寻找此Cookie相关的会话,从而取得会话上下文。取得会话之后会做一些安全校验,通常是校验User-Agent字段。这也是通常窃取别人的会话信息要同时窃取Cookie和User-Agent信息的原因。这一点也说明在浏览器上,用http协议访问Web服务器是不安全的,因为http是明文传输的,在局域网内抓包,很容易就窃取到Cookie和User-Agent信息,可以伪造请求。

    1.7 跨域

      跨域指的是从一个域下的资源上引用或跳转到另一个域下的资源。跨域在网页中是很常见的现象,比如在百度中搜索内容,然后点击某一个搜索结果,打开一个非百度的页面,这就有跨域。跨域有很多种情形,并不是每种跨域都会受到限制,主要受限的情形是iframe和ajax跨
    域。跨域限制是浏览器端和Web服务端在一个公共约定基础上的自主选择。

      服务端可以进行跨域限制,以简陋地防止页面被某些网站引用。Http有头部字段Origin和Referer字段来表明是从那个域和页面跳转过来的。在浏览器上进行超链接跳转或ajax请求,浏览器都会自动设置上。但如果Web客户端不设置上这些头信息,服务端就无法得知是否发生了跨域。

      服务端可以在应答的头部添加一些头信息,以告诉浏览器端应该采取哪些安全限制。下面介绍以下与跨域相关的一些头信息。

    1.7.1 Referer

      它是一个请求字段,用它来表名当前请求是从哪里发起的。

    1.7.2 Referrer-Policy

    它是一个请求字段。规定了Referer的发送策略。可选值有以下几种:

    1. 空字符串("")。若设为空串则默认按照浏览器的机制设置referrer的内容,默认情况下是和no-referrer-when-downgrade设置得一样。
    2. no-referrer。任何情况下都不发送Referrer信息
    3. no-referrer-when-downgrade。这是默认值。当从https网站跳转到http网站或者请求其资源时(安全降级HTTPS→HTTP),不显示referrer的信息,其他情况(安全同级HTTPS→HTTPS,或者HTTP→HTTP)则在referrer中显示完整的源网站的URL信息。
    4. same-origin。表示浏览器只会显示referrer信息给同源网站,并且是完整的URL信息。所谓同源网站,是协议、域名、端口都相同的网站。
    5. origin。表示浏览器在referrer字段中只显示源网站的源地址(即协议、域名、端口),而不包括完整的路径。
    6. strict-origin。该策略更为安全些,和origin策略相似,只是不允许referrer信息显示在从https网站到http网站的请求中(安全降级)。
    7. origin-when-cross-origin。当发请求给同源网站时,浏览器会在referrer中显示完整的URL信息,发个非同源网站时,则只显示源地址(协议、域名、端口)
    8. strict-origin-when-cross-origin。和origin-when-cross-origin相似,只是不允许referrer信息显示在从https网站到http网站的请求中(安全降级)。
    9. unsafe-url。浏览器总是会将完整的URL信息显示在referrer字段中,无论请求发给任何网站。

    Referrer Policy设置方法:

    1. 在Http的header中直接设置;
    2. 通过<meta>元素改变Referrer Policy,直接修改名为referrer的内容。
    <meta name="referer" content="origin">
    
    1. 给 <a>, <area>, <img>, <iframe>, 或者<link>元素设置referrerpolicy属性。
    <a href="http://www.baidu.com" referrerpolicy="origin">
    
    1. 如需设置不显示referrer信息时,也可以给 <a>, <area>, <link>元素设置rel的链接关系。
    <a href="http://www.baidu.com" rel="noreferrer">
    

    1.7.3 X-Frame-Options

      它是响应字段,用来给浏览器指示允许一个页面可否在<frame>, <iframe>, <embed> 或者 <object>中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面,从而避免 clickjacking 攻击。可取值:

    1. deny。表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
    2. sameorigin。表示该页面可以在相同域名页面的 frame 中展示。
    3. allow-from uri。表示该页面可以在指定来源的 frame 中展示。例如:
    X-Frame-Options: allow-from https://example.com/
    

    1.7.4 X-XSS-Protection

      这是响应字段,当检测到跨站脚本攻击 (XSS (en-US))时,浏览器将停止加载页面。可取值:

    • 0。禁止XSS过滤。
    • 1。启用XSS过滤(通常浏览器是默认的)。 如果检测到跨站脚本攻击,浏览器将清除页面(删除不安全的部分)。
    • 1;mode=block。启用XSS过滤。如果检测到攻击,浏览器不会清除页面,而是阻止页面加载。
    • 1; report=<reporting-URI> (Chromium only)。启用XSS过滤。 如果检测到跨站脚本攻击,浏览器将清除页面并使用CSP report-uri (en-US)指令的功能发送违规报告。

    1.7.5 Set-Cookie

      Set-Cookie是应答首部字段,其中含有先前由服务器通过Set-Cookie响应首部字段投放存储到客户端的Cookie信息。它的语法格式:

    SetCookie: name=value; name2=value2; name3
    

    其中有一个有与跨域相关的特定键值。

    1. HttpOnly。如果在cookie中设置了HttpOnly附加标志,那么js脚本将无法读取到cookie信息,这样能有效防止XSS攻击。
    2. Expires。Cookie的有效期。如果没有设置,那么就是内存cookie,浏览器关闭,cookie就会丢失;如果设置了Expires,那么就是硬盘cookie,cookie被存储到磁盘,下次启动浏览器,还可以读取到。
    3. Domain。cookie的适用域。它是使用endWith匹配方法的。
    4. Path。在domain基础上,进一步限定适用的路径。
    5. Secure。一个带有安全属性的 cookie 只有在请求使用SSL和HTTPS协议的时候才会被发送到服务器。然而,保密或敏感信息永远不要在 HTTP cookie 中存储或传输,因为整个机制从本质上来说都是不安全的,比如前述协议并不意味着所有的信息都是经过加密的。非安全站点(http:)已经不能再在 cookie 中设置 secure 指令了(在Chrome 52+ and Firefox 52+ 中新引入的限制)。
    6. SameSite。客户端传送cookie的规则限制。可取值:空字符串("")、Lax()、None、Strict。https下得设置成SameSite=None ; Secure才能在iframe、ajax跨域请求时携带cookie。

    1.7.8 Access-Control-Allow-Origin

      这是一个响应头部字段。用来告诉浏览器,在没有访问凭据时可以访问的域。在CORS时,需要搭配Vary头信息一起使用。如下:

    Access-Control-Allow-Origin: https://developer.mozilla.org
    Vary: Origin
    

    2.跨域

      对于跨域带来的问题,这里的解决思路不是让用户去修改浏览器设置,让浏览器不去进行相关的安全检查。而是在浏览器缺省的设置条件下,如何解决跨域问题。主要是这样的解决思路:

    1. 将服务端告诉浏览器端的跨域限制条件放开,以允许当前情形下跨域;
    2. 让浏览器端不认为这是在跨域,主要是使用代理技术;
    3. 针对cookie在某些情形下,因不满足浏览器的安全要求,局部被禁用的情形,则是从设法满足浏览器的安全要求,和自定义url参数或header,来实现cookie的功能。

    相关文章

      网友评论

        本文标题:HTTP基础及跨域

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