HTTP —— 超文本传输协议,用于规范客户端浏览器和服务端以何种格式进行通信和数据交互;HTTP由请求和响应构成的,是一个标准的客服端服务器模型。
HTTP请求响应过程
先简单的来了解以下HTTP的请求响应过程:1.地址解析:解析URL得到协议名,主机名,端口和对象路径,如果主机名不是IP地址而是域名的话,需要通过DNS(域名系统)进行解析为IP地址;2.封装HTTP请求报文:将URL地址按照HTTP格式封装成HTTP请求报文(请求行,请求消息头,空行,请求体)存放在客户都的Socket对象;3.建立TCP连接:HTTP工作开始之前先与Web服务器建立TCP连接;4.浏览器向Web服务发送请求报文(建立TCP之后存在客户都的Socket对象通过TCP发送给Web服务器);5.Web服务器接收请求并向浏览器发送响应报文(状态行,响应消息头,空行,响应体);6.Web服务器关闭TCP连接。
http模块引入
http模块是Node.js内置的核心模块,通过使用这个核心模块可以轻松地创建一个HTTP服务器,实现浏览器与Web服务器间的请求响应。
const http = require('http');
http.createServer() —— 创建Web服务器
通过使用http.createServer()来创建Web服务器实例:
// 创建Web服务器
const server = http.createServer();
.on() —— 监听 request 请求
为Web服务器绑定request事件,监听客户端发过来的request请求;只要客户端发来请求,就会触发request,从而调用事件处理函数;
// .on —— 监听request请求
server.on('request',function(req,res){
console.log('执行事件处理');
})
.listen() —— 启动Web服务器
调用 .listen( 端口 ,callback ) 方法来启动Web服务器;
server.listen('8080',function(){
console.log('Web Server Running ...')
})
用node命令执行文件;
在浏览器中去请求 http://127.0.0.1:8080 或 http://localhost ,会触发.listen() 执行事件处理;
server.on('request',function(req,res){ })
req对象 —— 请求
当服务器接收到客户端的请求就可以调用server.on()为服务器绑定request事件处理函数,同时可以在事件处理函数中访问客户端相关的数据和属性;
server.on('request',function(req,res){
console.log('访问客户端属性');
console.log('req.url',req.url);
console.log('req.method',req.method);
})
res对象 —— 响应
在request事件处理函数中,如果要访问服务器相关的数据或者属性可以使用res响应对象;
server.on('request',function(req,res){
const str = '准备向客户端发送数据...';
res.end(str); // 向客户端发送指定内容,并结束请求处理过程
})
用 node命令 执行文件;可以看到数据已经发到客户端,但出现数据乱码现象,如下:
解决中文乱码问题
为防止中文数据显示乱码,需要设置请求头 Content-Type:text/html,charset=utf-8 ;
res.setHeader('Content-Type','text/html;charset=utf-8');
动态响应
以上通过请求http://127.0.0.1:8080或http://localhost:8080获取的请求响应内容,现在是通过不同的url来响应不同的内容,也就是能够进行一个动态的内容响应;首先要先获取客户端请求的url地址,判断用户请求的url地址是否存在,不存在如何处理,存在又如何将数据内容响应给客户端;
const http = require('http');
const server = http.createServer();
server.on('request',function(req,res){
const url = req.url;
let content = '<h2>404 Not Found</h2>';
if(url === '/' || url === '/index.html'){
content = '<p> 当前处于/首页 </p>'
}
res.setHeader('Content-Type','text/html;charset=utf-8');
res.end(content);
})
server.listen('8080',function(){
console.log('Web Server running...');
})
用 node命令 执行,并通过浏览器请求地址http://127.0.0.1:8080或http://localhost:8080并修改url路径 /index.html 和 /my.html 进行测试:
http.request()
使用 http.request(options[,callback]) 来做一个 GET 请求,options 参数可以是一个对象,字符串或者URL对象,若为字符串,会自动使用url.parse()进行解析,若为URL对象,会自动使用转为options对象;options中的参数有很多,这里列举了几个:
下面来进行http.request()方法使用,请求本地搭建的服务器(127.0.0.1:3000)数据:
// request.js文件
const options = {
hostname:'localhost',
port:3000,
method:'GET',
path:'/api/swiperList'
}
// const options = 'http://127.0.0.1:3000/api/swiperList';
const request = http.request(options,(res)=>{
// console.log(res);
res.setEncoding('utf-8');
res.on('data',function(chunk){
console.log(JSON.parse(chunk));
})
})
request.on('error',function(err){
console.log("错误异常:",err.message);
})
request.end();
http.get()
使用http.get(options,[callback]),http.get()和http.request()中的options的参数接收相同,大多数的请求都是GET请求且不带请求体,所以http.get()和http.request()的区别是设置请求为GET且自动调用req.end();
// get.js文件
const http = require('http');
const options = {
hostname:'localhost',
port:3000,
method:'GET',
path:'/api/swiperList'
}
var data = '';
var request = http.request(options,(response)=>{
// console.log(response);
response.setEncoding('utf-8');
response.on('data',(chunk)=>{
// console.log(chunk);
data += chunk;
})
response.on('end',()=>{
JSON.parse(data).swiperList.map((item)=>{
console.log(item);
});
})
})
request.on('error',(error)=>{
console.log("请求异常:",error);
})
request.end();
后端解决跨域问题
前面通过http模块创建HTTP服务器,那么现在服务器通过前端页面发来的request请求时,例如前端页面是127.0.0.1:5500发出的请求是127.0.0.1:3000的请求,这里就存在跨域问题,浏览器的同源策略!
前端页面在讲Vue的时候讲过可以使用VScode中的一个小工具[ Live Server ]来进行模拟,那么如果不清楚的这里提供一个跳转地址:第十九篇 fetch请求
前端页面 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全国行政区</title>
</head>
<body>
<div id='app'>
<h2>全国行政区</h2>
<ul class="city">
</ul>
</div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$.ajax({
url:'http://127.0.0.1:3000'
}).then(res=>{
const rs = JSON.parse(res);
for(const i in rs.result){
$('.city').append('<li>'+rs.result[i].name+'</li>');
}
})
</script>
</body>
</html>
后端服务:(未处理跨域)
const http = require('http');
const fs = require('fs');
const server = http.createServer();
server.on('request',(req,res)=>{
let data = fs.readFileSync(__dirname + '/全国行政区数据.json')
res.end(data);
})
server.listen(3000,()=>{
console.log('Web Server Running ...')
})
测试效果
以上测试效果就是没有处理跨域的一个问题导致的,那么处理跨域的解决方法有很多种,这里不过的描述,等遇到再说,下面是通过这个后端来解决这个跨域的问题,设置以下3个属性:
Access-Control-Allow-Origin",'*'
Access-Control-Allow-Headers","X-Requested-With"
Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"
下面来通过http模块创建HTTP服务器和fs模块将已经准备好了的json读取之后响应回去给客户端;通过浏览器模拟客户端发起请求127.0.0.1:3000看是否能够获取到json数据的响应;
const http = require('http');
const fs = require('fs');
const server = http.createServer();
server.on('request',(req,res)=>{
// 解决跨域
res.setHeader("Access-Control-Allow-Origin",'*'); // *表示任何IP可以访问
res.setHeader("Access-Control-Allow-Headers","X-Requested-With");
res.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.setHeader("Content-Type","text/plain;charset=utf-8");
let data = fs.readFileSync(__dirname + '/全国行政区数据.json')
res.end(data);
})
server.listen(3000,()=>{
console.log('Web Server Running ...')
})
执行 node命令 将 服务器启动...
浏览器请求响应数据,如下可以看到客户端发起请求可以拿到json数据内容;
以上就是本篇的全部内容了,下面是本篇的一些补充信息,感谢大家的支持!
响应对象res常用的方法:
方法 | 描述 |
res.json() | 返回JSON数据 |
res.send() | 根据不同的内容,返回不同格式的HTTP响应 |
res.render | 渲染模板页面 |
res.redirect() | 重定向到指定的URL |
res.status() | 设置响应状态码,如:200,404,500... |
res.set() | 设置响应报头的信息 |
res.end() | 结束请求 - 响应循环 |