Node.js学习笔记

目录

Node.js简介

网站

注意事项

Buffer

简介

创建

方式一

方式二

方式三

buffer操作

buffer与字符串转换

buffer元素读取

中文

fs模块

writeFile

fs异步写入

fs同步写入

fs追加写入

fs流式写入

readFile

fs异步读取

fs同步读取

fs流式读取

复制

重命名

移动

删除

文件夹操作

创建

读取

删除

查看

Path模块

IP

端口

Http

请求报文

请求行

请求头

空行

请求体

响应报文

状态行

响应头

空行

响应体

创建Http服务

提取报文

提取报文的请求体

提取URL路径和字符串

提取URL路径和字符串2.0

HTTP请求练习

HTTP设置响应

HTTP响应练习

响应练习拓展

静态资源和动态资源

网站根目录或静态资源目录

URL

网站中的URL

网页中使用URL的场景

设置资源类型(mime)

GET和POST请求

GET

POST

区别

模块化

模块化项目

好处

暴露数据

导入模块

require注意事项

CommonJs模块化规范


Node.js简介

Node.js 是一个开放源代码、跨平台的 JavaScript 运行环境,开发者能够使用 JavaScript 编写服务器端的代码。通俗点说:就是一款应用程序,一款软件,构建于Google Chrome的V8 JavaScript引擎之上,提供高效的JavaScript解释和执行能力。采用了事件驱动、非阻塞I/O模型,适合构建高并发、实时应用。

网站

官网:Node.js (nodejs.org)

中文网站:Node.js 中文网 (nodejs.cn)

历史版本:https://registry.npmmirror.com/binary.html?path=node

下载长期支持版本,安装后,在命令提示符输入node -v,如果出现版本信息则代表安装成功。

运行:node 文件

注意事项

Node.js中不能使用BOM和DOM的API,可以使用console和定时器API。Node.js中的顶级对象为global。

例如,你可以在 global 对象上添加一个变量:

global.myVar = 'Hello, world!';

然后,在任何 Node.js 文件的任何地方,你都可以访问这个变量。

console.log(myVar) 
// 输出: Hello, world!

但是,需要注意的是,过度使用 global 对象可能会导致代码难以理解和维护,因为全局变量可能会导致意外的副作用和命名冲突。因此,尽量避免使用全局变量,而是考虑使用模块作用域(通过 module.exports 和 require)或闭包来组织你的代码。

Buffer

简介

Buffer中文译为缓冲区,是一个类似于Array的对象,用于表示固定长度的字节序列。换句话说,Buffer就是一段固定长度的内存空间,用于处理二进制数据。

特点:大小固定且无法调整、性能较好,可以直接对计算机内存进行操作、每个元素的大小为1字节。

创建

方式一

let buf = Buffer.alloc(2)
console.log(buf)
//输出<Buffer 00 00>

方式二

let buf = Buffer.allocUnsafe(3)
console.log(buf)
//输出<Buffer 00 00 00>

方式三

let buf = Buffer.from('buffer')
console.log(buf)
//输出<Buffer 62 75 66 66 65 72>

输出是数字,在Node.js中,Buffer 类是用来处理二进制数据的, Buffer.from('buffer') 创建一个 Buffer 对象时,实际上是将字符串 'buffer' 转换为字节形式存储。在计算机内部,所有数据最终都是以二进制形式存在的,包括字符也是按照特定字符编码转换成字节序列。(16)

62 对应于字母 'b'
75 对应于字母 'u'
66 对应于字母 'f'
66 对应于字母 'f'
65 对应于字母 'e'
72 对应于字母 'r'
//使用 .toString() 方法
//例buf.toString('utf-8'),这样会得到原始的字符串 "buffer"
console.log(buf.toString())
//buffer

除了将字符串转换为Buffer,还可以将数组转换为Buffer。

数组 [13, 14] 表示两个字节的数据,其中:

  • 数组的第一个元素 13 十进制转换为十六进制即为 0D
  • 数组的第二个元素 14 十进制转换为十六进制即为 0E

这里的 0d 和 0e 是按照字节的二进制格式进行十六进制表示的结果。在不同的上下文中,这两个字节可能对应不同的字符或其他类型的数据,具体含义取决于使用的编码或数据协议。

let buf = Buffer.from([13,14])
console.log(buf)
//输出<Buffer 0d 0e>

buffer操作

buffer与字符串转换

let buf = Buffer.from([105,108,111,118,101,121,111,117])
console.log(buf.toString())
//输出iloveyou

buffer元素读取

let buf = Buffer.from('hello')
console.log(buf[2].toString())
//输出108

在 UTF-8 编码下,字符串 'hello' 对应的字节序列为:

  • 'h' 对应字节 0x68
  • 'e' 对应字节 0x65
  • 'l' 对应字节 0x6c
  • 'l' 对应字节 0x6c
  • 'o' 对应字节 0x6f

访问 buf[2] 时,获取的是该缓冲区第三个字节,也就是字符 'l' 对应的字节值,在十进制下等于 108,若想将此字节还原为其代表的字符,可以使用 buf[2].toString('utf8'),这样会输出 'l'

中文

let buf = Buffer.from('缓冲区')
console.log(buf)
//输出<Buffer e7 bc 93 e5 86 b2 e5 8c ba>

占用九个字节,一个utf-8的中文占用三个字节。

fs模块

可以实现与硬盘的交互,例如文件删除、重命名、移动、创建、文件内容的读写、以及文件夹的相关操作。

writeFile

应用场景:下载文件、安装软件、保存程序日志如Git、编辑器保存文件、视频录制

fs异步写入

//导入fs模块
const fs = require('fs');
//参数:路径、写入内容、(可选)、回调
fs.writeFile('./text', 'fs写入', err => {
  // err 写入失败: 错误对象  写入成功: null
  if(err){
    console.log('写入失败');
    return;
  }
  console.log('写入成功');
});

fs同步写入

//同步写入
fs.writeFileSync('./text', '同步写入');

fs追加写入

异步追加写入

//引入 fs 模块
const fs = require('fs');
//调用 appendFile
fs.appendFile('./text', ',异步追加写入', err => {
  //判断
  if(err){
    console.log('追加写入失败');
    return;
  }
  console.log('追加写入成功');
});

同步追加写入

fs.appendFileSync('./text', '\r\n同步追加写入')

writefile追加写入,如果不写可选参数{flag:'a'},会将原来的写入内容清空

fs流式写入

const fs = require('fs');
// 创建写入流对象 
const ws = fs.createWriteStream('./text');
// write
ws.write('问渠那得清如许\r\n');
ws.write('为有源头活水来\r\n');
// 关闭通道
ws.close();

readFile

应用场景:电脑开机、程序运行、编辑器打开文件、查看照片、播放视频、播放音乐、Git查看日志、上传文件、查看聊天记录

fs异步读取

fs.readFile('./text', (err, data) => {
  if(err) {
    console.log('读取失败');
    return;
  }
  console.log('读取成功')
  console.log(data.toString());
});
/**读取成功
问渠那得清如许
为有源头活水来
*/

fs同步读取

let data = fs.readFileSync('./text');
console.log(data.toString());

fs流式读取

const fs = require('fs');
//创建读取流对象
const rs = fs.createReadStream('./text');
// 绑定 data 事件
rs.on('data', chunk => {
  console.log(chunk.toString());
});
// end 可选
rs.on('end', () => {
  console.log('读取完成');
});

复制

//复制
const fs = require('fs');
const process = require('process');
const rs = fs.createReadStream('./text');
const ws = fs.createWriteStream('./text1');
rs.pipe(ws);

重命名

// 导入 fs 模块
const fs = require('fs');
// 调用 rename 方法
fs.rename('./text1', './text2', err => {
  if(err) {
    console.log('重命名失败');
    return;
  }
  console.log('重命名成功');
});

移动

// 导入 fs 模块
const fs = require('fs');
//文件的移动
fs.rename('./text2', './code/text2', err => {
  if(err) {
    console.log('移动失败');
    return;
  }
  console.log('移动成功');
})

删除

// 导入 fs 模块
const fs = require('fs');
// 调用 unlink 
fs.unlink('./text', err => {
  if(err) {
    console.log('删除失败');
    return;
  }
  console.log('删除成功');
});
// 导入 fs 模块
const fs = require('fs');
// 调用 rm 方法
fs.rm('./text', err => {
  if (err) {
    console.log('删除失败');
    return;
  }
  console.log('删除成功');
})

文件夹操作

创建

// 创建文件夹
fs.mkdir('./file', err => {
  if(err) {
    console.log('创建失败');
    return;
  }
  console.log('创建成功');
});

// 递归创建
fs.mkdir('./a/b/c', {recursive: true},err => {
  if(err) {
    console.log('创建失败');
    return;
  }
  console.log('创建成功');
});

读取

// 读取文件夹
fs.readdir('./file', (err, data) => {
  if(err){
    console.log('读取失败');
    return;
  }
  console.log('读取成功');
});

删除

// 删除文件夹
fs.rmdir('./file', err => {
  if(err){
    console.log('删除失败');
    return;
  }
  console.log('删除成功');
});

//递归删除
fs.rmdir('./a', {recursive: true},err => {
  if(err){
    console.log(err);
    return;
  }
  console.log('删除成功');
});

//rm 
fs.rm('./a', {recursive: true},err => {
  if(err){
    console.log(err);
    return;
  }
  console.log('删除成功');
});

查看

// 导入 fs 模块
const fs = require('fs');

// stat
fs.stat('../a/file', (err, data) => {
  if(err){
    console.log('操作失败');
    return;
  }
  // isFile 
  console.log(data.isFile());
  // isDirectory
  console.log(data.isDirectory());
});

Path模块

//resolve 拼接得到完整路径
fs.writeFileSync(__dirname + '/text', 'love');
console.log(path.resolve(__dirname + '/text'))

// sep 分隔符
console.log(path.sep); 
// windows  \  Linux  /

let str = 'E:\\NodeJS\\path\\path.js';

// basename 返回路径字符串中的最后一部分,即文件名:path.js
console.log(path.basename(str));

// dirname 返回路径字符串中除了最后一个部分(文件名)之外的部分,即目录路径;E:\\NodeJS\\path\\path
console.log(path.dirname(str));

// extname 返回路径中的文件扩展名部分,不包括点,即'js'
console.log(path.extname(str));

IP

标识网络中的设备,实现设备间通信

端口

网络通信中的逻辑通道标识符,每个IP地址后面跟着一个端口号,共同确定了网络中特定的服务或进程。

Http

是互联网上数据通信的基础协议,主要用于在万维网上发送和接收信息。它定义了消息的格式化方式以及传输方式,并规定了Web服务器和浏览器在接收到不同命令时应采取何种响应动作。

请求报文

HTTP请求报文是客户端(如Web浏览器)向服务器发送请求时采用的数据格式,以优快云为例:

请求行

c56e0b4ea5674c64be7989cd9d9b3a78.png

方法(Method):描述了要执行的操作,如GET(获取数据)、POST(新增数据)、PUT(更新)、PATCH(更新)、DELETE(删除)等。
请求URI(Request-URI):指定了要访问的资源位置,可以是绝对URI或者相对URI。
HTTP版本(HTTP-Version):表明使用的HTTP协议版本,例如HTTP/1.1。

请求头

fe7b6a28225e436fa54b00dab8a03cf1.png

包含一系列键值对,用来传递额外的请求信息,比如:
Host:指定服务器的域名和端口号。
Accept:指定客户端能够处理的媒体类型。
Content-Type:当发送请求体时,指示其内容的MIME类型。
Authorization:携带认证信息。
Cookie:传送客户端的cookie信息。
其他很多不同的头字段,用于缓存控制、代理转发、客户端能力声明等。

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers

空行

请求头和请求体之间的一个空行,用于区分这两部分。

请求体

可选部分,不是所有请求都有请求体。在POST、PUT等方法中,通常会携带请求数据,例如表单数据、JSON对象、文件上传等。

响应报文

HTTP响应报文是服务器对客户端请求的回应,其格式同样具有固定的结构,以优快云为例:

86aec05c37c64e3f838d1ed3717b0906.png

状态行

HTTP版本:表明服务器使用的HTTP协议版本,如HTTP/1.1。
状态码(Status Code):三位数字代码,如200、404、500等,分别代表成功、客户端错误和服务器错误。https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
状态消息(Reason-Phrase):对状态码的文字描述,如OK、Not Found、Internal Server Error等。

响应头

同请求头一样,也是一系列键值对,包含服务器返回的各种附加信息,例如:
Content-Type:告知客户端响应体的内容类型。
Content-Length:响应体的大小(字节数)。
Set-Cookie:服务器向客户端设置cookie。
Location:重定向新的URL地址。
其他如缓存控制、服务器信息、实体标签等相关的头部信息。

空行

响应头和响应体之间的一个空行,用于区分这两部分。

响应体

包含了请求资源的实际内容,可能是HTML文档、JSON数据、图片、视频等各种类型的数据。

创建Http服务

// 导入 http 模块
const http = require('http')
// 创建服务对象
const server = http.createServer((request,response)=>{
  response.setHeader('content-type', 'text/html;charset=utf-8');
  response.end('你好,http'); 
})
// 监听端口, 启动服务
server.listen(4000,()=>{
  console.log('服务器启动中.....')
})

提取报文

// 导入 http 模块
const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => {
  //获取请求方法
  // console.log(request.method);
  //获取url
  console.log(request.url);  // 只包含 url 中的路径与查询字符串
  //获取 HTTP 协议的版本号
  // console.log(request.httpVersion);
  //获取 HTTP 的请求头
  // console.log(request.headers.host);
  response.end('http'); 
});
// 监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

提取报文的请求体

// 导入 http 模块
const http = require('http');

// 创建服务对象
const server = http.createServer((request, response) => {
  let body = '';
  // 绑定 data 事件
  request.on('data', chunk => {
    body += chunk;
  })
  // 绑定 end 事件
  request.on('end', () => {
    console.log(body);
    response.end('Hello HTTP');
  });
});

// 监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});
<!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>Document</title>
</head>
<body>
  <form action="http://127.0.0.1:9000" method="post" >
    <input type="text" name="username">
    <input type="text" name="password">
    <input type="submit" value="提交">
  </form>
</body>
</html>

username=hello&password=123456

提取URL路径和字符串

//导入 http 模块
const http = require('http');
// 导入 url 模块
const url = require('url');
//创建服务对象
const server = http.createServer((request, response) => {
  // 解析 request.url 
  //浏览器输入http://127.0.0.1:9000/search?keyword=h5&a=4
  console.log(request.url);
  // /search?keyword=h5

  //parse用于解析URL并且返回一个URL对象
  let res = url.parse(request.url, true);
  //路径
  let pathname = res.pathname;
  console.log(pathname)
  //search

  //查询字符串
  let keyword = res.query.keyword;
  console.log(keyword)
  //h5
  response.end('url');
});
//监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});
let res1 = url.parse(request.url, true);
console.log(res1)
//输出如下
Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: '?keyword=h5',
  query: [Object: null prototype] { keyword: 'h5' },
  pathname: '/search',
  path: '/search?keyword=h5',
  href: '/search?keyword=h5'
}

提取URL路径和字符串2.0

//导入 http 模块
const http = require('http');

//创建服务对象
const server = http.createServer((request, response) => {
  //实例化 URL 的对象
  // let url = new URL('/search?a=100&b=200', 'http://127.0.0.1:9000');
  let url = new URL(request.url, 'http://127.0.0.1');
  //输出路径 /search
  console.log(url.pathname);
  //输出 keyword 查询字符串  h5
  console.log(url.searchParams.get('keyword'));
  response.end('url new');
});

//监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

HTTP请求练习

const http = require('http')
const server = http.createServer((request,response)=>{
  let {method} = request
  let {pathname} = new URL(request.url,'http://127.0.0.1')
  if(method === 'GET' && pathname ==='/login')
  {
    response.end('login page')
  }
  else if(method === 'GET' && pathname ==='/reg')
  {
    response.end('reg')
  }
  else{
    response.statusCode = 404
    response.end('Not Fond')
  }
})
server.listen(9000,()=>{
  console.log('启动中...')
})

HTTP设置响应

// 导入 http 模块
const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => {
  // 设置响应状态码
  // response.statusCode = 404;
  //  响应状态的描述 
  // response.statusMessage = 'hello';
  // 响应头
  // response.setHeader('content-type', 'text/html;charset=utf-8');
  // 设置重名响应头
  // response.setHeader('res', ['a','b','c']);
  // 响应体的设置
  response.write('hahah');
  response.end('你好');      
});
// 监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

HTTP响应练习

//导入 http 模块
const http = require('http');
// 创建服务对象
const server = http.createServer((request, response) => {
  response.end(`
    <!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>Document</title>
      <style>
        td{
          padding: 20px 40px;
        }
        table tr:nth-child(odd){
          background: #aef;
        }
        table tr:nth-child(even){
          background: #fcb;
        }
        table, td{
          border-collapse: collapse;
        }
      </style>
    </head>
    <body>
      <table border="1">
        <tr><td></td><td></td><td></td></tr>
        <tr><td></td><td></td><td></td></tr>
        <tr><td></td><td></td><td></td></tr>
        <tr><td></td><td></td><td></td></tr>
      </table>
      <script>
        //获取所有的 td
        let tds = document.querySelectorAll('td');
        //遍历
        tds.forEach(item => {
          item.onclick = function(){
            this.style.background = '#222';
          }
        })
      </script>
    </body>
    </html>
  `); 
});

//监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

优化,将end()中的代码单独放在一个HTML文件

//导入 http 模块
const http = require('http');
const fs = require('fs');

//创建服务对象
const server = http.createServer((request, response) => {
  //读取文件内容
  let html = fs.readFileSync(__dirname + 'table.html');
  response.end(html); //设置响应体
});

//监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

响应练习拓展

在上一个练习基础上,分别创建Css、JS、Html文件后,根据路径读取

//导入 http 模块
const http = require('http');
const fs = require('fs');
//创建服务对象
const server = http.createServer((request, response) => {
  //获取请求url的路径
  let {pathname} = new URL(request.url, 'http://127.0.0.1');
  if(pathname === '/'){
    //读取文件内容
    let html = fs.readFileSync(__dirname + '/10_table.html');
    response.end(html); //设置响应体
  }else if(pathname === '/index.css'){
    //读取文件内容
    let css = fs.readFileSync(__dirname + '/index.css');
    response.end(css); //设置响应体
  }else if(pathname === '/index.js'){
    //读取文件内容
    let js = fs.readFileSync(__dirname + '/index.js');
    response.end(js); //设置响应体
  }else{
    response.statusCode = 404;
    response.end('<h1>404 Not Found</h1>')
  }
});
//监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

静态资源和动态资源

静态资源是指长时间不发生改变的资源,例如图片、视频、CSS文件、JS文件、HTML文件、字体文件等;动态资源是指内容经常更新的资源,例如百度首页、京东搜索列表页面等

ba3db35ef48546d5843930a20760dfd9.png

/**
 * 创建一个 HTTP 服务,端口为 9000,满足如下需求
 * GET  /index.html        响应  page/index.html 的文件内容
 * GET  /css/app.css       响应  page/css/app.css 的文件内容
 * GET  /images/logo.png   响应  page/images/logo.png 的文件内容
 */
//导入 http 模块
const http = require('http');
const fs = require('fs');
const path = require('path');
//声明一个变量
let mimes = {
  html: 'text/html',
  css: 'text/css',
  js: 'text/javascript',
  png: 'image/png',
  jpg: 'image/jpeg',
  gif: 'image/gif',
  mp4: 'video/mp4',
  mp3: 'audio/mpeg',
  json: 'application/json'
}

//创建服务对象
const server = http.createServer((request, response) => {
  if(request.method !== 'GET'){
    response.statusCode = 405;
    response.end('<h1>405 Method Not Allowed</h1>');
    return;
  }
  //获取请求url的路径
  let {pathname} = new URL(request.url, 'http://127.0.0.1');
  //声明一个变量
  let root = __dirname + '/page';
  // let root = __dirname + '/../';
  //拼接文件路径
  let filePath = root + pathname;
  //读取文件 fs 异步 API
  fs.readFile(filePath, (err, data) => {
    if(err){
      console.log(err);
      //设置字符集
      response.setHeader('content-type','text/html;charset=utf-8');
      //判断错误的代号
      switch(err.code){
        case 'ENOENT':
          response.statusCode = 404;
          response.end('<h1>404 Not Found</h1>');
        case 'EPERM':
          response.statusCode = 403;
          response.end('<h1>403 Forbidden</h1>');
        default:
          response.statusCode = 500;
          response.end('<h1>Internal Server Error</h1>');
      }
      
      return;
    }
    //获取文件的后缀名
    let ext = path.extname(filePath).slice(1);
    //获取对应的类型
    let type = mimes[ext];
    if(type){
      //匹配到了                          text/html;charset=utf-8
      if(ext === 'html'){
        response.setHeader('content-type', type + ';charset=utf-8');
      }else{
        response.setHeader('content-type', type);
      }
    }else{
      //没有匹配到
      response.setHeader('content-type', 'application/octet-stream');
    }
    //响应文件内容
    response.end(data);
  })
  
});
//监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

这个实例中,如果在JS下面创建一个abc.js,那么可以直接通过127.0.0.1:9000/js/abc.js读取内容。

网站根目录或静态资源目录

HTTP服务在哪个文件夹中寻找静态资源那个文件夹就是静态资源目录,也称之为网站根目录,上面实例的网站根目录就是page.

URL

统一资源定位符,是一种互联网上的标准资源地址格式,用于指向互联网上某一资源的地址。URL在网络世界中就像现实世界中的地址一样,帮助用户和应用程序找到并访问特定的网络资源。

网站中的URL

网站中的URL主要分为:相对路径、绝对路径

绝对路径

绝对路径可靠,相对容易理解

http://aaa.com/file直接向目标资源发送请求,易理解,网站外链
//aaa.com/file与页面URL的协议拼接成完整URL后发送请求,大型网站
/file与页面URL的协议、主机名、端口拼接成完整URL发送请求,中小网站

相对路径

相对路径在发送请求时,需要与当前页面的URL路径进行计算,得到完整URL后发请求,多用于学习阶段,例如当前网站URL:http://www.aa.com/file/a.html

./css/a.csshttp://www.aa.com/file/css/a.css
a/a.jshttp://www.aa.com/file/a/a.js
../img/a.pnghttp://www.aa.com/img/a.png
../../mp3/b.mp3http://www.aa.com/mp3/b.mp3

网页中使用URL的场景

a标签href

link标签href

script标签src

img标签src

video audio 标签src

from中的action

AJAX请求中的URL

设置资源类型(mime)

媒体类型是一种标准,用来表示文档,文件或字节流的性质和格式,mime 类型结构:[type]/[subType]

例:text/html   text/css   image/jpeg 

HTTP服务可以设置响应头Context-Type来表明响应体的MIME类型,浏览器会根据该类型决定如何处理。常见文件对应的mime类型:

 html: 'text/html',
  css: 'text/css',
  js: 'text/javascript',
  png: 'image/png',
  jpg: 'image/jpeg',
  gif: 'image/gif',
  mp4: 'video/mp4',
  mp3: 'audio/mpeg',
  json: 'application/json'

对于未知的资源类型,可以选择application/octet-stream类型,浏览器在遇到该类型的响应时,会对响应体内容进行独立存储,也就是常见的下载效果

GET和POST请求

GET

在地址栏直接输入url访问

点击a链接

link标签引入css

script标签引入js

video与audio引入多媒体

img引入图片

from中的method为get

ajax中的get请求

POST

from中的method为post

ajax中的post请求

区别

1.作用:GET主要获取数据,POST主要提交数据’

2.参数位置:GET带参数请求是将参数放到URL之后,POST带参数请求是将参数放到请求体中

3.安全性:POST比GET相对安全一些,因为浏览器中参数会暴露在地址栏

4.GET请求大小有限制,一般为2K,而POST请求则没有大小限制

模块化

将一个复杂的程序文件依据一定的规范拆分为多个文件的过程,其中拆分出的每个文件就是一个模块,模块的内部数据是私有的,可以通过暴露内部数据以便其他模块使用。

模块化项目

编码时按照模块一个一个编码的,整个项目就是一个模块化项目。

好处

1.防止命名冲突

2.高复用性

3.高可靠性

暴露数据

模块暴露数据的方式有两种:

1. module.export = value

2.exports.name = value

module.exports可以暴露任意数据,不能使用exports = value的形式暴露数据,模块内部module与exports的隐式关系:exports = module.exports = {}

function Ha(){
  console.log('汉诺塔');
}
function Max(){
  console.log('求最大....');
}

//暴露数据
module.exports = {
Ha,Max
}

// exports 暴露数据
exports.Ha = Ha;
exports.Max = Max;

// module.exports 可以暴露`任意`数据
module.exports = 'hello';
module.exports = 520;

// 不能使用 `exports = value`的形式暴露数据
exports = 'iloveyou' // 不允许 X

exports = module.exports = {}
console.log(module.exports === exports);  //true

exports = module.exports = {Ha:Ha}
exports.Max = Max;

exports = 'iloveyou' // 不允许 X

导入模块

在模块中使用require传入文件路径即可引入文件:const mk = require('./mk')

require注意事项

1.对于自己创建的模块,导入路径建议写相对路径,且不要省略./和../

2.js和json文件导入时可以不写后缀。C/C++编写的node拓展文件也可以不写后缀

3.如果导入其他类型的文件,会议js文件进行处理

4. 如果导入的路径是个文件夹,则会首先检查该文件夹下package.json文件中main属性对应的文件,如果main属性不存在,或者package.json不存在,则检查文件夹下的idnex.js和index.json,如果依旧找不到,就报错

5. 导入Node.js内置模块时,直接require模块的名字即可

//导入模块
// const Ha = require('./me.js');

//省略后缀 JS
// const tiemo = require('./me');

//导入 JSON 文件
// const duanzi = require('./duanzi');
// console.log(duanzi);//对象

//如果后缀不一样,前面一样,先导入js

//导入其他类型的文件
const test = require('./test');

console.log(test);
// 调用函数
// Ha();

CommonJs模块化规范

module.exports、exports以及require这些都是CommonJs模块化规范中的内容,而Node.js是实现了CommonJs模块化规范,二者的关系有点像JavaScript与ECMAScript。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值