http基础

基本概念

HTTP,为超文本传输协议。是互联网应用最为广泛的一种网络协议,所有的 www 文件都必须遵守这个标准。HTTP 可以分为两个部分,即请求和响应。

HTTP 请求:

HTTP 请求由 3 个部分构成,分别是:状态行,请求头(Request Header),请求正文。

image

实例:

image

HTTP 响应:

HTTP 响应三个部分构成,分别是:状态行,响应头(Response Header),响应正文。

image

HTTP头信息

先介绍一下HTTP请求头信息

header 解释 实例
Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html
Accept-Encoding 表示浏览器有能力解码的编码类型 Accept-Encoding: compress, gzip
Accept-Language 表示浏览器所支持的语言类型 Accept-Language: en,zh
Cache-Control 指定请求和响应遵循的缓存机制 Cache-Control: no-cache
Connection 是否需要持久连接(HTTP 1.1 默认进行持久连接即为 keep-alive, HTTP 1.0 则默认为 close) Connection: close
Cookie HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 Cookie: $Version=1; Skin=new;
Host 表示请求的服务器网址 Host: www.zcmhi.com
User-Agent 用户代理,简称UA,它是一个特殊字符串头,使得服务器能够识别客户端使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content-Length 请求的内容长度 Content-Length: 348
Referer 先前访问的网页的地址 Referer: http://www.zcmhi.com/archives/71.html
Content-Type 内容的类型,GET 请求无该字段,POST 请求中常见的有 application/x-www-form-urlencoded 为普通的表单提交,还有文件上传为 multipart/form-data Content-Type: application/x-www-form-urlencoded

HTTP响应头信息
Connection, Content-Encoding, Content-Type 和请求头的内容差不多,不再赘述。

header 解释 实例
Date 原始服务器消息发出的时间 Date: Tue, 15 Nov 2010 08:12:31 GMT
Last-Modified 请求资源的最后修改时间 Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT
Expires 响应过期的日期和时间 Expires: Thu, 01 Dec 2010 16:00:00 GMT
Set-Cookie 设置Http Cookie,下次浏览器再次访问的时候会带上这个 Cookie 值 Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
Server 服务器软件名称 Server: Apache/1.3.27 (Unix) (Red-Hat/Linux)

详细信息请参考: HTTP响应头和请求头信息对照表

HTTP状态码

  • 1xx : 表示请求已经接受了,继续处理。
  • 2xx : 表示请求已经处理掉了。
  • 3xx : 重定向。
  • 4xx : 一般表示客户端有错误,请求无法实现。
  • 5xx : 一般为服务器端的错误。

常见状态码:

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 304 - 通知浏览器复用本地缓存
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误

Content-Type

Content-Type标头告诉客户端实际返回的内容的内容类型。

  • text/html : HTML格式
  • text/plain :纯文本格式
  • application/json: JSON数据格式
  • application/x-www-form-urlencoded :
    中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
  • multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式

浏览器缓存

浏览器整个缓存策略的过程如下图:

image

HTTP中与缓存相关的字段

Cache-Control, Last-modified, Etag

Cache-Control

通过cache-control的指令可以告诉客户端或是服务器如何处理缓存。常见的请求指令如下:

  • no-cache -- 缓存要经过服务器验证;如果资源没有过期,直接返回304状态码,告知浏览器复用本地缓存。
  • no-store -- 禁止缓存
  • max-age -- 有效的缓存时间。max-age的设置会造成只要请求的链接不变且仍在有效缓存时间内,当服务端更新文件后客户端并不知道文件已经更新。所以我们通常会给打包完成的js文件加上一段hash码,若js内容不变则hash码不变,这样就可以使用静态资源缓存。

Last-modified

客户端第一次发起请求后,服务端返回200,响应体会包含Last-Modified的属性标记此文件在服务端最后被修改的时间。当客户端再次发起请求后,客户端把第一次Last-Modified的值存储在If-Modified-Since里面发送给服务端来验证资源有没有修改。如果有修改正常服务端返回资源,状态码200,如果没有修改只返回响应头,状态码304,告知浏览器资源的本地缓存还可用。

Etag

资源的唯一标识,用于标识URL对象是否改变。服务端会在客户端第一次请求某一个URL时把这个标识放到响应头传到客户端。当客户端再次发起这个请求时,会把第一次的Etag值存储在If-None-Match里面发送给服务端来验证资源有没有修改。

const http = require('http');
const fs = require('fs');

http.createServer(function (req, res) {
    const html = fs.readFileSync('F:/http/lesson5-(last-modified,etag)/test.html', 'utf8')
    if (req.url === '/') {
        res.writeHead(200, {
            'Content-type': 'text/html'
        });
        res.end(html)
    }
    if (req.url === '/script.js') {
        const etag = req.headers['if-none-match'];
        if(etag === '777') {
            res.writeHead(304, {
                'Content-type': 'text/javascript',
                'Cache-Control': 'max-age=2000, no-cache', // no-cache 缓存要经过服务器验证  no-store 禁止缓存
                'Last-modified': '123',
                'Etag': '777', // etag 用于标示URL对象是否改变,
                // 当客户端再次试图访问某个文件,发现缓存过期,客户端会在本次请求的请求头里携带If-Moified-Since和If-None-Match(即之前的Etag值)这两个字段,
                // 服务器通过这两个字段来判断资源是否有修改,如果有修改则返回状态码200和新的内容,
                // 如果没有修改返回状态码304便知道了本地缓存虽然过期但仍然可以用,于是加载本地缓存。
            });
            res.end('')
        } else {
            res.writeHead(200, {
                'Content-type': 'text/javascript',
                'Cache-Control': 'max-age=2000, no-cache', // no-cache 缓存要经过服务器验证  no-store 禁止缓存
                'Last-modified': '123',
                'Etag': '777', // etag 用于标示URL对象是否改变,
                // 当客户端再次试图访问某个文件,发现缓存过期,客户端会在本次请求的请求头里携带If-Moified-Since(即之前的Last-modified的值)和If-None-Match(即之前的Etag值)这两个字段,
                // 服务器通过这两个字段来判断资源是否有修改,如果有修改则返回状态码200和新的内容,
                // 如果没有修改返回状态码304便知道了本地缓存虽然过期但仍然可以用,于是加载本地缓存。
            });
            res.end('console.log("script loaded twice")')
        }

    }
}).listen(8888);

console.log('server listening on 8888');

HTTP Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。

Cookie主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

创建cookie
服务器使用Set-Cookie响应头部向用户代理(一般是浏览器)发送Cookie信息。一个简单的Cookie可能像这样:

Set-Cookie: <cookie名>=<cookie值>

nodejs中设置cookie方法如下:

http.createServer(function (req, res) {
    const html = fs.readFileSync('F:/http/lesson6-cookie/test.html', 'utf8')
    if (req.url === '/') {
        res.writeHead(200, {
            'Content-type': 'text/html',
            'Set-Cookie': ['id=123; max-age=2', 'abc=456; HttpOnly'] // HttpOnly 那么通过js脚本将无法读取到cookie信息,防止xss攻击
        });
        res.end(html)
    }
}).listen(8888);

为避免跨域脚本 (XSS) 攻击,通过JavaScript的 Document.cookie API无法访问带有 HttpOnly 标记的Cookie。


参考文档:

原文地址:https://www.cnblogs.com/renzhiwei2017/p/15542791.html