app.js
自动生成:
安装node snippets插件,输node-http-server
var http = require('http');
http.createServer((request, response)=> {
//设置响应头
response.writeHead(200, {'Content-Type': 'text/plain'});
//输出并结束响应
response.end('Hello World');
}).listen(8081); //监听端口
console.log('Server running at http://127.0.0.1:8081/');
手动输入
const http = require('http');// 引用创建网站服务器的模块
const url = require('url');// 用于处理url地址
const app = http.createServer();// 创建web服务器(app就是网站服务器对象)
// 当客户端有请求来,请求在服务器端通过事件来触发
app.on('request', (req, res) => { //请求的事件名称,事件处理函数(请求对象,响应对象)
if (req.method == 'POST') { // 获取请求方式 req.method,根据不同的请求方式做不同的响应
res.end('post')
} else if (req.method == 'GET') {
res.end('get')
}
// 获取请求地址 req.url, 根据不同的请求地址,返回不同内容
// if (req.url == '/index' || req.url == '/') {
// 若没有写请求地址(访问 localhost:3000),此时req.url是一个'/'(要默认访问首页,加上|| req.url == '/')
// res.end('<h2>欢迎来到首页</h2>'); 打印响应内容(是代码)
// }else { //请求的地址不存在
// res.end('not found');
// }
// 获取请求头 req.headers
// console.log(req.headers['accept']); 获取到其中具体某一项
//设置响应头:状态码、内容类型(html)、字符集
res.writeHead(200, {
'content-type': 'text/html;charset=utf8' //响应体里有中文
});
res.write('this');
//parse被弃用?
// 1) 要解析的url地址
// 2) 将查询参数解析成对象形式
//let { query, pathname } = url.parse(req.url, true);
//console.log(query.name)
//console.log(query.age)
//根据浏览器不同的请求地址,返回不同的响应体
//if (pathname == '/index' || pathname == '/') {
// res.end('<h2>欢迎来到首页</h2>');//除非把content-type改成text/html,否则不解析
//}else if (pathname == '/list') {
// res.end('welcome to listpage'); //此响应体是纯文本类型
//}else { //请求的地址不存在
// res.end('not found'); //res.end(); 结束响应,必须得写
//}
//新的?
const myURL=new URL(req.url,'http://localhost:3000/');
// res.end('<h2>hello user</h2>');
});
// 监听端口(否则无法向外界提供服务)
app.listen(3000);
console.log('网站服务器启动成功');
创建了网站服务器必须监听端口,才能向外界提供服务
执行: nodemon 文件名.js
访问:在本地电脑启动的该服务器,用域名localhost:3000
HTTP协议
超文本传输协议,是客户端(用户)和服务器端(网站)请求和应答的标准,规范了请求报文和响应报文
在HTTP请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,并且要遵守规定好的格式。
请求报文
HTTP请求报文由三部分组成:请求行,请求头、空行 / 请求正文
-
请求行:请求类型(GET/POST/PUT...) URL路径 HTTP协议的版本
-
请求头:键值对格式,描述客户端请求哪台主机及其端口,以及客户端的一些环境信息等
-
空行:空行就是\r\n (POST请求时候有?必须有?)
-
请求正文:当使用POST等方法时,通常需要客户端向服务器传递数据。这些数据就储存在请求正文中(GET方式是保存在url地址后面,不会放到这里,相应的请求体是空的)
行 POST /s?ie=utf-8 HTTP/1.1
头 Host: ![]()atguigu.com
Cookie: name=guigu
Content-type: application/x-www-form-urlencoded 告知服务器请求体是什么类型的
User-Agent: chrome 83
体 username=admin&password=admin
1. 请求方式(Request Method)
告诉服务器端当前请求要做的事件类型
GET:请求数据(如刷新、跳转地址、浏览器自动发送的图标请求)
POST:发送数据(如登录操作、表单),POST相对GET更安全
2. 请求地址(Request URL)
app.on('request', (req, res) => {
req.method // 获取请求方法
req.url // 获取请求地址
req.headers // 获取请求报文
});
访问: localhost:3000/index(/index是请求地址)
3. 请求参数
客户端向服务器端发送请求时,有时需要携带一些客户信息,客户信息需要通过请求参数的形式传递到服务器端,比如登录操作。
GET请求参数
- 参数被放在浏览器地址栏中,如
http://localhost:3000/index?name=zhangsan&age=20?name=zhangsan&age=20 (?后表示携带的参数,用=分割的键值对,传递多个参数用&连接) - 参数获取需要借助系统模块url,url模块用来处理url地址
const url = require('url');用console.log(req.url)打印:/index?name=zhangsan&age=20
POST请求参数
- 参数被放置在请求体中进行传输(在Network的Form Data里查看)
- POST参数是通过事件的方式接收的,需要使用data事件和end事件,分多次接收
- 使用querystring系统模块将参数转换为对象格式
先开启服务器端:nodemon 文件名.js
const http = require('http');
const app = http.createServer();
const querystring = require('querystring');// 处理请求参数模块
app.on('request', (req, res) => {
let postParams = ''; //用于存储POST参数
//参数1:事件名称 参数2:事件处理函数
req.on('data', params => { //当请求参数传递的时候触发data事件
postParams += params; //分多次接收当前传递过来的POST参数
});
req.on('end', () => { //当参数传递完成的时候触发end事件
console.log(querystring.parse(postParams)); //把字符串转换为对象,querystring被弃用,下载npm install query-string ?
//postParams是username=xxx&password=xxx
});
res.end('ok'); //对每次请求,服务器端都要响应结束,否则客户端一直处于等待状态
});
app.listen(3000);// 监听端口
console.log('网站服务器启动成功');
在客户端访问:
<body>
<!--
method: 指定当前表单提交的方式,可以是GET或POST,不写默认是GET
action: 指定当前表单提交的地址,这里用已经开启的自己的服务器
-->
<form method="post" action="http://localhost:3000">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit">
</form>
<!-- 发现在表单POST请求类型后有GET请求,因为点击表单按钮发送POST请求后
表单发送了跳转页面的默认行为,跳转行为默认是GET类型 -->
</body>
响应报文
-
响应头:响应头用于描述服务器的基本信息,以及客户端如何处理数据
-
空格:CRLF(即 \r\n)分割
-
消息体:服务器返回给客户端的数据
响应行 HTTP协议的版本 响应状态码 响应状态字符串 响应头 键值对格式,对响应体内容做相关的描述(如类型是什么?长度是多少?压缩方式是哪种?...) 空行必须有 响应体是主要的返回结果,html内容放在响应的报文当中来传输。
行 HTTP/1.1 200 OK
头 Content-Type: text/html;charset=utf-8
Content-length: 2048
Content-encoding: gzip
空行
体 <html>
<head>
</head>
<body>
<h1>尚硅谷</h1>
</body>
</html>
1. 常用的响应状态码
- 在Network里查看状态码:Status
- 200 请求成功
- 401 未授权
- 403 被禁止
- 404 请求的资源没有被找到
- 500 服务器端错误
- 400 客户端请求有语法错误(如请求路径错了/请求参数不匹配)
- 为客户端设置不同的状态码
- 设置响应头:res.writeHead()的第一个参数
2. 内容类型 Content-Type
指定响应返回的是什么内容类型:
res.writeHead()的第二个参数,该参数是个对象,存储响应头的信息
- text/html 返回的是html文件
- text/css 返回的是css文件
- application/javascript 返回的是js文件
- image/jpeg
- application/json
app.on('request', (req, res) => {
res.writeHead(200, { // 设置响应报文(不写状态码默认是200)
'Content-Type': 'text/plain;charset=utf8' //返回的响应体是纯文本
});
});