😁 作者简介:一名大三的学生,致力学习前端开发技术
⭐️个人主页:夜宵饽饽的主页
❔ 系列专栏:前端js专栏
👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇气
🔥前言:
这是有关Express请求和响应的总结和自己的理解,会有相应的基础知识理解,让初学者更好的使用Express,欢迎大家更好的补充和纠正
1 URL的组成部分
-
协议
协议确定任何传输请求,我们主要是处理http和https。其他常见的协议还有file和ftp
-
主机名
主机名标识服务器,运行在本地计算机和本地网络的服务器可以简单的表示,比如一个单词,或一个数字IP。在internet环境下,主机名通常以一个顶级域名结尾,比如.com或.net 另外,也许还会给予主机名的前缀,一般来说都是www开头的
-
端口
每一个服务器都是有一系列的端口号,一些端口号比较特殊,如80和443端口,如果省略端口值,默认就是80端口,如果不使用80和443端口,需要一个大于1023的端口号,通常容易记忆的
-
路径
URL 中影响应用程序的第一个组成部分通常是路径(在考虑协议、主机名和端口的基础上做决定很合理,但是不够好)。路径是应用中的页面或其他资源的唯一标识。
-
查询字符串
查询字符串是一种键值对集合,是可选的。它以问号(?)开头,键值对则以与号(&)分隔开。所有的名称和值都必须是 URL 编码的。对此,JavaScript 提供了一个嵌入式的函数 encodeURIComponent 来处理。例如,空格被加号(+)替换。其他特殊字符被数字
型字符替换。
-
信息片段
信息片段(或散列)被严格限制在浏览器中使用,不会传递到服务器,用它控制单页应用或AJAX富应用越来越普遍
2 HTTP请求方法
HTTP协议确定了客户端与服务器通信的请求方法集合(通常称为HTTP verbs),我们最常见的是GET和POST请求
3 请求报头
浏览器发送给服务器的不仅仅是URL,还有更多的“隐藏信息”,所有能够确保你了解请求对象头文件属性的信息都将作为请求报头发送。
4 响应报头
和浏览器以请求报头的形式发送隐藏信息到服务器,当服务器响应时,同样会回传一些浏览器没必要渲染和显示的信息。,报头还会指出响应信息是否被压缩,以及使用的是哪种编码。响应报头还可以包含关于浏览器对资源缓存时长的提示。优化网站时需要着重考虑这一点,
🔺 有时候会返回关于服务器的信息,一般会指出服务器的类型,有时会包含操作系统的详细信息,返回服务器信息会存在一个安全问题,这样会给黑客提供一个可乘之机,从而使站点陷入危险。重视安全的服务器一般会忽略此信息,或者提供虚假信息:
app.disable('x-powered-by')
5 互联网媒体类型
内容类型报头信息极其重要,没有它,客户端很难判断如何渲染接收到的内容。内容类型报头就是一种互联网媒体类型,由一个类型、一个子类型以及可选的参数组成。例如,text/html;charset=UTF-8 说明类型是 text,子类型是 html,字符编码是 UTF-8。互联网编号分配机构维护了一个官方的互联网媒体类型清单(http://www.iana.org/assignments/media-types/media-types.xhtml)。我们常见的 content type、Internet media type 和 MIME type 是可以互换的。MIME(多用途互联网邮件扩展)是互联网媒体类型的前身,它们大部分是相同的。
6 请求体
除请求报头外,请求还有一个主体(就像作为实际内容返回的响应主体一样),一般来说GET是没有请求体的,但是POST有,常见的请求体的媒体类型是application/x-www-form-urlendcoded,是键值对类型的,媒体类型是multipart/form-data,它是一种更为复杂的格式,AJAX请求,它是application/json
7 参数
“参数”这个词可以有很多种解释,它通常是困惑的源头。对于任何一个请求,参数可以来自查询字符串、会话(请求 cookies,详见第 9 章)、请求体或指定的路由参数(详见第 14章)。在 Node 应用中,请求对象的参数方法会重写所有的参数。因此我们最好不要深究。我们将学习保存不同类型参数的专用属性,我认为这能够减少困惑。
8 请求对象
请求对象,通常命名为req ,其是始于Node的一个核心对象http.InconmingMessage的实例,Express添加了一些附加功能
-
⭐️ req.params
一个数组,包含命名过的路由参数
-
req.param(name)
放回命名的路由参数,或者GET请求参数或POST请求参数,建议忽略此方法
-
⭐️ req.query
一个对象,包含以键值对存放的查询字符串参数(通常是GET请求)
-
⭐️ req.body
一个对象,包含POST请求参数,要使req.body可用,需要中间件能够解析请求正文内容类型
-
req.route
关于当前匹配路由的信息,主要用于路由调试
-
⭐️ req.cookies/req,singnedCookies
一个对象,包含从客户端传递来的cookies值
-
⭐️ req.headers
从客户端接收到的请求报头
-
req.accepts([type])
用来确定客户端是否接收一个或一组指定的类型(可选类型可以是单个MIEE类型,如application/json,一个逗号分隔集合或是一个数组)。写公共API的人对该方法很感兴趣
-
⭐️ req.ip
客户端的IP地址
-
⭐️ req.path
请求路径(不包含协议,主机,端口,查询字符串)
-
req.host
返回客户端所报告的主机名,这些信息可以伪造,所以不应该用于安全目的
-
req.xhr
请求由AJAx发起的会返回true
-
req.protocol
用于标识请求的协议(http或https)
-
req.url/req.originUrl
返回了路径和查询字符串(不包含协议,主机,端口),req.url出于内部的目的,则可以重写的
-
req.qcceptedLanguages
一个简便方法,用来返回客户端首选的一组语言,这些信息是从请求报头中解析而来的
9 响应对象
响应对象,通常命名为res,其是始于Node核心对象http.ServerResponse的实例,Express添加了一些附加功能
-
⭐️ res.status(code)
设置HTTP状态代码。Express默认为200(成功),所以你可以使用这个方法返回状态404,500,或任何一个其他的状态码,对于重定向(301,302,303,307)有一个更好的方法:redirect
-
res.set(name,value)
设置响应头,这通常不需要手动设置
-
⭐️ res.cookie(name,value,[options]),res.clearCookie(name,[options])
设置或清除客户端cookies值,需要中间件支持
-
⭐️ res.redirect([status],url)
重定向浏览器,默认状态码是302,通常,应该尽量减少重定向,除非永久移动一个页面,这种情况应该使用永久移动码(301)
-
⭐️ res.send(body),res.send(status,body)
向客户端发送响应及可选的状态码。Express 的默认内容类型是 text/html。如果你想改为 text/plain,需要在 res.send 之前调用 res.set(‘Content-Type’,‘text/plain’)。如果 body 是一个对象或一个数组,响应将会以 JSON 发送(内容类型需要被正确设置),不过既然你想发送 JSON,我推荐你调用 res.json。
-
⭐️ res.json(json),res.json(status,json
向客户端发送 JSON 以及可选的状态码。
-
res.jsonp(json),req.jsonp(status,json)
向客户端发送 JSONP 及可选的状态码。
-
res.type
用于设置Content-Type头信息,基本上相当于res.set(‘Content-Type’,‘type’),只是如果提供一个没有斜扛的字符串,它会试图把其当作文件的扩展名映射为一个互联网媒体类型,例如:res.type(‘txt’)会将Content-Type设为text/plain。这种功能可能在部分领域有用(例如自动提供不同的多媒体文件,但是通常应该避免使用它,以便明确设置正确的互联网媒体类型)
-
⭐️ res.format(object)
这个可以根据请求报头发送不同的内容,这是它在API中的主要用途,例如:res.format({‘text/plain’:‘hi there’,‘text/html’:‘<-b-> hi there</-b->’})
-
⭐️ res.attachment([filename]),res.download(path,[filename],[callback])
这两种方法会将响应报头 Content-Disposition 设为 attachment,这样浏览器就会选择下载而不是展现内容。你可以指定 filename 给浏览器作为对用户的提示。res.download 可以指定要下载的文件,而 res.attachment 只是设置报头。另外,你还要将内容发送到客户端
-
⭐️ res.sendFile(path,[option],[callback])
这个方法可根据路径读取指定文件并将内容发送到客户端。使用该方法很方便。使用静态中间件,并将发送到客户端的文件放在公共目录下,这很容易。然而,如果你想根据条件在相同的 URL 下提供不同的资源,这个方法可以派上用场。
-
res.links(links)
设置链接响应报头。这是一个专用的报头,在大多数应用程序中几乎没有用处
-
res.locals,res.render(view,[locals],callback)
res.locals 是一个对象,包含用于渲染视图的默认上下文。res.render 使用配置的模请求和响应对象板引擎渲染视图(不能把 res.render 的 locals 参数与 res.locals 混为一谈,上下文
在 res.locals 中会被重写,但在没有被重写的情况下仍然可用)
10 获取更多的信息
由于 JavaScript 的原型继承,有时确切知道自己在做什么是很困难的。Node 提供了Express 扩展对象,添加的程序包同样也可以扩展它们。有时候弄明白到底什么是可用的是个挑战。通常,我推荐逆向作业:如果你正在寻找某些功能,首先要查看 Express 的 API文档(http://expressjs.com/api.html)。Express 的 API 相当齐全,你一般都会在这里找到想要的。
如果你需要的信息没在文档中,有时就不得不深入研究 Express 源码(https://github.com/visionmedia/express/tree/master)。我鼓励你这么做,它并没有想象中那么可怕。下面是
Express 源码的路径说明。
• lib/application.js
Express 主接口。如果想了解中间件是如何接入的,或视图是如何被渲染的,可以看
这里。
• lib/express.js
这是一个相对较短的 shell,是 lib/application.js 中 Connect 的功能性扩展,它返回一个
函数,可以用 http.createServer 运行 Express 应用。
• lib/request.js
扩展了 Node 的 http.IncomingMessage 对象,提供了一个稳健的请求对象。关于请求对
象属性和方法的所有信息都在这个文件里。
• lib/response.js
扩展了 Node 的 http.ServerReponse 对象,提供响应对象。关于响应对象的所有属性和
方法都在这个文件里。
• lib/router/route.js
提供基础路由支持。尽管路由是应用的核心,但这个文件只有不到 200 行,你会发现它非常地简单优雅。
在你深入研究 Express 源码时,或许需要参考 Node 文档(http://nodejs.org/api/http.html),尤其是 HTTP 模块部分。