0

0

聊聊怎么使用Node.js创建一个简单的HTTP服务器

青灯夜游

青灯夜游

发布时间:2022-06-27 13:16:41

|

3709人浏览过

|

来源于掘金社区

转载

怎么使用nodejs创建http服务器?下面本篇文章给大家介绍一下使用node创建一个简单的http服务器的方法,希望对大家有所帮助!

聊聊怎么使用Node.js创建一个简单的HTTP服务器

1. 使用Node.js直接运行JavaScript脚本

node.js基于node.jsChrome引擎运行v8代码,因此我们可以摆脱浏览器环境,直接在控制台中运行js代码,比如下面这个js代码

console.log('hello world');

控制台中直接使用hello world即可运行

1.png


2. 创建一个简单的HTTP服务器

node的内置模块node.js提供了基本的http服务的能力,基于http规范,我们可以使用CommonJS导入require模块进行使用http模块中有一个http函数能够让我们创建一个createServer服务器 其接收一个回调函数作为参数,这个回调函数接收两个参数 -- httprequest

  • response包括所有客户端请求的信息,比如request、请求头url、请求方式和请求体等
  • header主要用于返回信息给客户端,封装了一些操作响应体相关的操作,比如response方法就可以让我们自定义返回体的头部信息和状态码

当我们将响应体处理好了之后,调用response.writeHead方法就可以将响应体发送给客户端 使用response.end()函数只是帮我们创建了一个createServer对象,并没有让其开启监听,我们还需要调用Server对象的server方法才可以进行监听,真正作为一个服务器开始运行

  • listen方法的第一个参数是监听的端口号,第二个参数则是绑定的主机listen,第三个参数是一个回调函数,会被ip模块异步调用,当遇到错误的时候,就能够在这个回调函数的第一个参数中获取到抛出的异常 ,我们可以选择对异常进行处理,让我们的服务器更加健壮

下面是使用http模块创建一个简单服务器的例子

const { createServer } = require('http');
const HOST = 'localhost';
const PORT = '8080';

const server = createServer((req, resp) => {
  // the first param is status code it returns  
  // and the second param is response header info
  resp.writeHead(200, { 'Content-Type': 'text/plain' });  
  
  console.log('server is working...');  
  
  // call end method to tell server that the request has been fulfilled
  resp.end('hello nodejs http server');
});

server.listen(PORT, HOST, (error) => {  
if (error) {  
  console.log('Something wrong: ', error);   
   return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

可以直接尝试用http运行它,创造一个属于你的服务器!服务器运行后,浏览器访问http://localhost:8080即可访问到这个服务器

2.png

也可以使用node运行它,这样当我们的代码发生变化的时候就不需要手动终止程序再重新运行了

npm i -g nodemon

建议全局安装它,这样就可以直接使用,不需要通过nodemon去使用 使用也很简单,直接将npx nodemon命令改成node命令即可

nodemon http-server.js

3.png


3. 加上类型提示

前面我们在使用nodemon以及createServer对象的时候,看不到任何的语法提示,必须随时跟着resp官方文档去边用边查,有点不方便 但是没关系,我们可以使用nodets文件帮助我们提供语法提示功能,注意,我们不是使用.d.ts进行开发,只是使用它的语法提示功能而已

  1. 初始化项目 -- ts
  2. 安装npm init -y -- @types/node
  3. 在项目目录下创建pnpm i @types/node -D文件,将jsconfig.json排除在外,没必要对其进行检查
{  "compilerOptions": {
    "checkJs": true
  },  
  "exclude": ["node_modules", "**/node_modules/*"]
}

不知道你是否有发现上面的代码其实是有一处错误的呢?node_modules能够帮助我们检查类型错误问题,可以根据需要选择是否开启 可以看到,开启检查后立马就给我们提示了参数类型不匹配的问题

4.png

这时候将鼠标悬浮在checkJs方法上,就能够看到该方法的签名

5.png

可以看到,原来listen参数需要是port类型,但是我们定义的时候是number类型,所以没匹配上,将其修改为stringnumber即可 而且可以直接查看到相关8080的文档,不需要打开api官方的文档找半天去查看了


4. 返回多个字符串的响应体

前面我们的简单node中只返回了一句话,那么是否能够返回多句话呢? 这就要用到http server对象的resp方法了,write只能够返回一次内容,而是用end方法,我们可以多次写入内容到响应体中,最后只用调用一次write,并且不传递任何参数,只让他完成发送响应体的功能

const { createServer } = require("http");
const HOST = "localhost";
const PORT = 8080;

const server = createServer((req, resp) => {
  resp.writeHead(200, { "Content-Type": "text/plain" });  
  console.log("server is working...");  
  
  // write some lorem sentences
  resp.write("Lorem ipsum dolor sit amet consectetur adipisicing elit.\n");
  resp.write("Omnis eligendi aperiam delectus?\n");
  resp.write("Aut, quam quo!\n");

  resp.end();
});

server.listen(PORT, HOST, (error) => {
  if (error) {    
  console.log("Something wrong: ", error);    
  return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

这次我们写入了三句话,现在的效果就变成这样啦

6.png


5. 返回html

我们不仅可以返回字符串给浏览器,还可以直接读取end文件的内容并将其作为结果返回给浏览器 这就需要用到另一个html的内置模块 -- Node.js,该模块提供了文件操作的功能 使用fs可以异步进行读取文件的操作,但是它不会返回fs.readFile对象,因此我们需要传入回调去处理读取到文件后的操作 还可以使用promise进行同步阻塞读取文件,这里我们选择异步读取

const { createServer } = require("http");
const fs = require("fs");
const HOST = "localhost";

const PORT = 8080;const server = createServer((req, resp) => {
  // change the MIME type from text/plain to text/html
  resp.writeHead(200, { "Content-Type": "text/html" });  
  
  // read the html file content
  fs.readFile("index.html", (err, data) => { 
     if (err) {  
      console.error(      
        "an error occurred while reading the html file content: ",
        err
      );      throw err;
    }    
    console.log("operation success!");

    resp.write(data);
    resp.end();
  });
});

server.listen(PORT, HOST, (error) => {
  if (error) {    
  console.log("Something wrong: ", error);    
  return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

现在的结果就像下面这样:

7.png

成功将fs.readFileSync返回注意:这里需要将响应头的html改为**Content-Type**,告知浏览器我们返回的是**text/html**文件的内容,如果仍然以**html**返回的话,浏览器不会对返回的内容进行解析,即便它是符合**text/plain**语法的也不会解析,就像下面这样:

8.png


6. 返回JSON

当我们需要编写一个后端服务器,只负责返回接口数据的时候,就需要返回**html**格式的内容了,相信聪明的你也知道该怎么处理了:

imgAK
imgAK

一站式AI图像处理工具

下载
  1. json类型设置为MIME
  2. application/json的时候传入的是resp.write字符串,可以使用json处理对象后返回
const { createServer } = require("http");
const HOST = "localhost";
const PORT = 8080;

const server = createServer((req, resp) => { 
 // change the MIME type to application/json
  resp.writeHead(200, { "Content-Type": "application/json" });  
  
  // create a json data by using an object  
  const jsonDataObj = {
      code: 0,    
      message: "success",    
      data: {  
          name: "plasticine",      
          age: 20,      
          hobby: "coding",
    },
  };

  resp.write(JSON.stringify(jsonDataObj));
  resp.end();
});

server.listen(PORT, HOST, (error) => {
  if (error) { 
     console.log("Something wrong: ", error);    
     return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

结果如下:

9.png


7. 返回pdf文件

和之前返回JSON.stringify文件的思路类似,都是一个设置响应头html类型,读取文件,返回文件内容的过程 但是这次我们搞点不一样的 我们的思路是在服务器运行的时候生成一个MIME文件,并将它返回 还需要将pdf的类型改为MIME生成application/pdf文件需要用到一个库 -- pdf

pnpm i pdfkit

首先我们编写一个创建pdfkit文件的函数,因为创建pdf文件还需要进行一些写入操作,不确定什么时候会完成,但是我们的请求必须等到pdf文件创建完成后才能得到响应 所以我们需要将它变成异步进行的,返回一个pdf

/**
 * @description 创建 pdf 文件
 */const createPdf = () => {
   return new Promise((resolve, reject) => {
       if (!fs.existsSync("example.pdf")) {      
       // create a PDFDocument object      
       const doc = new PDFDocument();
       
       // create write stream by piping the pdf content.
       doc.pipe(fs.createWriteStream("example.pdf"));   
        
      // add some contents to pdf document
      doc.fontSize(16).text("Hello PDF", 100, 100);   
         
      // complete the operation of generating PDF file.
      doc.end();
    }

    resolve("success");
  });
};

这里使用到了管道操作,将promise对象的内容通过管道传到新创建的写入流中,当完成操作后我们就通过PDFDocument告知外界已经创建好resovle文件了 然后在服务端代码中调用

const server = createServer(async (req, resp) => {
  // change the MIME type to application/pdf
  resp.writeHead(200, { "Content-Type": "application/pdf" });  
  
  // create pdf file  
  await createPdf();  
  
  // read created pdf file
  fs.readFile("example.pdf", (err, data) => {
      if (err) { 
       console.error(        
        "an error occurred while reading the pdf file content: ",
        err
      );      
      throw err;
    }    
    console.log("operation success!");

    resp.end(data);
  });
});

server.listen(PORT, HOST, (error) => {
  if (error) {
      console.log("Something wrong: ", error);    
      return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

现在浏览器就可以读取到创建的pdf文件了

10.png


8. 返回音频文件

思路依然是一样的,读取一个音频文件,然后通过管道将它送到pdf对象中再返回即可

const { createServer } = require("http");
const { stat, createReadStream } = require("fs");
const HOST = "localhost";
const PORT = 8080;

const server = createServer((req, resp) => {
  // change the MIME type to audio/mpe
  resp.writeHead(200, { "Content-Type": "audio/mp3" });  
  const mp3FileName = "audio.mp3";

  stat(mp3FileName, (err, stats) => {
    if (stats.isFile()) {      
      const rs = createReadStream(mp3FileName);      
      
      // pipe the read stream to resp
      rs.pipe(resp);
    } else {
      resp.end("mp3 file not exists");
    }
  });
});

server.listen(PORT, HOST, (error) => {
  if (error) {    
  console.log("Something wrong: ", error);    
  return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

效果如下

11.png

打开后就是一个播放音频的界面,这是resp提供的对音频文件的展示,并且打开控制台会发现有返回音频文件

11-2.png

注意:将音频文件流通过管道传到chrome后,不需要调用**resp**方法,因为这会关闭整个响应,导致音频文件无法获取

12.png

13.png


9. 返回视频文件

视频文件和音频文件的处理是一样的,只是**resp.end()**的类型要改成MIME,其他都一样

const { createServer } = require("http");
const { stat, createReadStream } = require("fs");
const HOST = "localhost";
const PORT = 8080;
const server = createServer((req, resp) => {  
// change the MIME type to audio/mpe
  resp.writeHead(200, { "Content-Type": "audio/mp4" });  
  const mp4FileName = "video.mp4";

  stat(mp4FileName, (err, stats) => { 
     if (stats.isFile()) {      
     const rs = createReadStream(mp4FileName);      
     // pipe the read stream to resp
      rs.pipe(resp);
    } else {
      resp.end("mp4 file not exists");
    }
  });
});

server.listen(PORT, HOST, (error) => { 
 if (error) {    
 console.log("Something wrong: ", error);    
 return;
  }  
  console.log(`server is listening on http://${HOST}:${PORT} ...`);
});

14.png


总结

我们学会了:

  • 如何使用video/mp4创建一个Node服务器
  • http加上类型提示
  • 如何返回字符串响应体
  • 如何返回js
  • 如何返回html
  • 如何生成并返回JSON文件
  • 如何返回音频文件
  • 如何返回视频文件

虽然内容简单,但还是希望你能跟着动手敲一敲,不要以为简单就看看就算了,看了不代表会了,真正动手实现过后才会找到自己的问题

更多node相关知识,请访问:nodejs 教程

相关专题

更多
Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

公务员递补名单公布时间 公务员递补要求
公务员递补名单公布时间 公务员递补要求

公务员递补名单公布时间不固定,通常在面试前,由招录单位(如国家知识产权局、海关等)发布,依据是原入围考生放弃资格,会按笔试成绩从高到低递补,递补考生需按公告要求限时确认并提交材料,及时参加面试/体检等后续环节。要求核心是按招录单位公告及时响应、提交材料(确认书、资格复审材料)并准时参加面试。

38

2026.01.15

公务员调剂条件 2026调剂公告时间
公务员调剂条件 2026调剂公告时间

(一)符合拟调剂职位所要求的资格条件。 (二)公共科目笔试成绩同时达到拟调剂职位和原报考职位的合格分数线,且考试类别相同。 拟调剂职位设置了专业科目笔试条件的,专业科目笔试成绩还须同时达到合格分数线,且考试类别相同。 (三)未进入原报考职位面试人员名单。

52

2026.01.15

国考成绩查询入口 国考分数公布时间2026
国考成绩查询入口 国考分数公布时间2026

笔试成绩查询入口已开通,考生可登录国家公务员局中央机关及其直属机构2026年度考试录用公务员专题网站http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/examResult/written_result.html,查询笔试成绩和合格分数线,点击“笔试成绩查询”按钮,凭借身份证及准考证进行查询。

9

2026.01.15

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

65

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

36

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

75

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

21

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

34

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 8.6万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

Node.js-前端工程化必学
Node.js-前端工程化必学

共19课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号