首页 > 编程语言 >nodejs 入门基本概念

nodejs 入门基本概念

时间:2023-05-15 22:01:20浏览次数:49  
标签:Node 缓存 浏览器 入门 nodejs cache js 基本概念 请求

nodejs 的诞生

  Node.js 是2009的时候由大神 Ryan Dahl 开发的。Ryan 的本职工作是用 C++ 写服务器,后来他总结出一个经验,一个高性能服务器应该是满足“事件驱动,非阻塞 I/O”模型的。C++ 开发起来比较麻烦,于是 Ryan 就想找一种更高级的语言,以便快速开发。

  Ryan 发现 JS 语言本身的特点就是事件驱动并且是非阻塞 I/O 的,跟他的思路正是绝配。第二点,Chrome 的 JS 引擎,也就是 V8 引擎是开源的,而且性能特别棒。于是 Ryan 就基于 V8 开发了 Node.js。

nodejs与浏览器环境

  在 Node.js 出现之前,最常见的 JavaScript 运行时环境是浏览器(我们平时写的代码跑在浏览器环境中)。浏览器为 JavaScript 提供了 DOM API,2009 年初 Node.js 出现了,它是由 Ryan Dahl 基于 Chrome V8 引擎开发的 JavaScript 运行时环境,所以 Node.js 也是 JavaScript 的一种宿主环境。

Node.js 不是浏览器,所以它不具有浏览器提供的 DOM API,比如 Window 对象、Location 对象、Document 对象、HTMLElement 对象、Cookie 对象等等。但是,Node.js 提供了自己特有的 API,比如全局的 global 对象,也提供了当前进程信息的 Process 对象,操作文件的 fs 模块,以及创建 Web 服务的 http 模块等等。这些 API 能够让我们使用 JavaScript 操作计算机,也可以开发 web 服务器。

nodejs 是什么

官方定义:Node.js 是一个开源和跨平台的 JavaScript 运行时环境。

怎么理解这个 JavaScript 运行时环境 ?顾名思义,是一个可以运行 JavaScript 的环境。这里的环境主要包含以下两个方面:

  1. 提供了编译、执行 JavaScript 的底层能力
  2. 提供了一系列接口,使开发者可以通过 JavaScirpt 调用系统底层能力(例如网络,文件读写等)

前者是由 Chrome V8 引擎提供的,而后者则是由一个底层由 C,C++ 编写的高性能的事件驱动的异步 I/O 库 libuv  所提供。

Node.js 内置的模块很丰富,具体可以查看nodejs 官网

通俗理解:nodejs 能让js 代码在浏览器之外执行,且能与操作系统进行交互、能操作文件、操作网络等。

nodejs 扩展了前端的边界

  在nodejs 这个执行环境中,我们可以与操作系统进行通信、能控制计算机,通过这个平台做很多的事情,如写一些web服务,客户端工具软件、打包工具等等。有了这样的一个平台,我们干的事情相比只能依赖在浏览器中完全不是一个级别的。

模块化

  nodejs 正式发布的时候,JavaScript 还没有标准的模块机制,nodejs一开始采用了CommonJS规范。后面JavaScript 标准的模块机制ES Modules诞生,浏览器开始逐步支持ES Modules。Node.js 从v13.2.0之后也引入了规范的ES Modules机制,同时兼容早期的CommonJS。

现在我们写 Node.js 模块的时候,可以有 3 种方式:

  1. 直接采用最新的ES Modules
  2. 采用ES Modules,通过 Babel 编译成CommonJS 规范。
  3. 仍然使用旧的CommonJS规范,预计未来 Node.js 在很长一段时间内依然会同时兼容ES Modules和CommonJS。

什么是npm

  模块化的目的是使代码可以更好地复用,同时为了更方便的使用别人写的模块或者分享自己的模块。推出了包管理工具,我们叫他npm,它允许我们以包的形式从共享仓中发布和下载模块。

  NPM 的全称是Node Package Manager是一个将 Node.js 的模块以包的形式组织和管理的工具。

npm script

NPM Scripts 是指在package.json文件中配置scripts属性,在其中指定脚本命令:

// package.json
{
  ... //其他配置
  "scripts": {
    "eslint": "eslint ziyue.js"
  }
}

NPM Scripts 能够执行对应的 Node 命令,是因为 NPM 在安装模块的时候,不仅将模块自身安装到node_modules目录下,还会在node_modules目录下创建一个.bin的子目录,将模块包中的命令行脚本安装到.bin目录下,并在 NPM Script 执行时设置系统的环境变量 PATH 包含node_modules/.bin目录,这样就能够正常执行脚本了。

如执行:

npm run eslint

就相当于执行了:

node ./node_modules/.bin/eslint xx.js

网络部分

  作为前端工程师,少不了要和 Web 打交道。通常情况下,前端工程师主要负责“端”的部分,也就是浏览器这一头的功能实现,后端工程师负责另一头,也就是服务器上的逻辑实现。当我们打开一个网页的时候,浏览器会向服务器发送 HTTP 请求,服务器根据请求的内容处理数据,将正确的数据返回。可以说,HTTP 协议将浏览器与服务器连接在了一起。

  因为 Web 开发中的许多问题既与客户端有关也与服务端有关,所以前端工程师很有必要了解 HTTP 协议。比如要优化性能,加快页面的打开速度,就需要理解 TCP 协议和 HTTP 协议,理解连接是如何建立的,数据是如何传输的。有兴趣可以参考之前记录的 http 相关知识点

理解 MIME 类型

浏览器可以处理多种格式的媒体文件,遵循的标准叫做 MIME

MIME 标准以type/subtype,即主类型/子类型,来表示一个文件的格式。MIME 类型对大小写不敏感,通常都写成小写形式。

HTTP 请求常见的主类型如下:

类型

描述

典型示例

text

表明文件是普通文本,理论上是人类可读

text/plain, text/html, text/css, text/javascript

image

表明是某种图像。不包括视频,但是动态图(比如动态 gif)也使用image类型

image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon

audio

表明是某种音频文件

audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav

video

表明是某种视频文件

video/webm, video/ogg

application

表明是某种二进制数据

application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf

浏览器的请求头中的 Accept 字段包含该请求期望的 MIME type,可以有多个,以逗号分隔。

所以,Accept: image/webp,image/apng,image/*,*/*;q=0.8表示浏览器期望的格式依次是image/webp、image/apng、image/*、*/*。 MIME 类型支持通配符*,最后的q=0.8表示相对品质因子,也就是说客户端“期望”是这个类型的权重,这个值给服务器参考,如果有多个可能返回的类型带有品质因子,服务器优先返回品质因子大的类型。

浏览器缓存策略

  静态资源文件一般不会变化,所以当客户端请求过某个文件之后,浏览器可以将这个文件缓存下来。这么做可以节省 HTTP 请求,既能够降低服务器的带宽消耗,也能够提升用户的访问速度。在 HTTP 协议中,动作 GETOPTIONS 是支持缓存的。

浏览器支持两种标准的缓存策略:强缓存和协商缓存。

浏览器缓存策略根据响应头的cache-control 来控制。

Cache-Control

Cache-Control 通用消息头字段,被用于在 http 请求和响应中,通过该字段来实现缓存机制。

通俗理解:告诉浏览器,当前这个资源要怎么缓存。

指令可缓存性

  1. public:表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。
  2. private:表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。比如:Cache-Control: private, max-age=360000,意思:中间层(代理)或者说CDN 不缓存此资源,只有浏览器可以缓存
  3. no-cache:每次都去进行协商缓存,确定资源是否有变更,一般用在index.html。 资源会缓存到本地。强制要求缓存把请求提交给原始服务器进行验证 (协商缓存验证)。
  4. no-store:不进行强制缓存和协商缓存,直接拉取最新的资源,资源不缓存到本地,即不使用任何缓存。

强缓存

服务器返回资源的时候带有Cache-Control响应头,这个策略叫做强缓存

响应头只要带有cache-control 就使用强缓存策略,当然值不能是no-store不进行缓存

Cache-Control响应头的最常用格式为:

Cache-Control: max-age=<seconds>

其中 seconds 是缓存的时间,单位是秒。

当浏览器请求资源得到的响应带有Cache-Control响应头时,浏览器会将该资源缓存到本地。当浏览器下一次访问该资源时,同时满足以下 3 个条件,浏览器会直接使用本地的资源,不发起 HTTP 请求

  1. 两次请求的 url 完全相同(包括了 host、pathname、query
  2. 请求的动作是 GET
  3. 请求头不带有Cache-Control: no-cachePragma: no-cache这两个信息

 

强缓存的状态码是200,带上from memory cache / from disk memory

协商缓存

协商缓存,以 HTTP 内容协商的方式来实现的缓存。协商缓存规定,浏览器发起 HTTP 请求时,服务器可以返回Last-Modified响应头,这个响应头的值是一个时间戳。如果服务器这么做了,那么浏览器会缓存这个资源,并且在今后请求该资源的时候,会带有if-modified-since请求头,它的值是上一次Last-Modified响应头中的时间戳。

  服务器收到带有if-modified-since请求头的请求,根据请求头中的时间戳,对文件进行判断,如果文件内容在该时间戳之后到当前时间里没有被修改,那么服务器返回一个 304 响应,该响应表示只有 HEAD 没有 BODY。浏览器如果收到 304 响应,就会以缓存的内容作为 BODY。

  除来Last-Modified响应头,还有一个 Etag 响应头,它的机制和Last-Modified大同小异,只是把Last-Modified的时间戳换成Etag签名,相应地把If-Modified-Since字段换成If-None-Match字段,其中Etag的值可以用资源文件的 MD5 或 sha 签名。  

  协商缓存为什么要有两种呢?

  因为,有时候我们的网站是分布式部署在多台服务器上,一个资源文件可能在每台服务器上都有副本,相应地资源文件被修改时候,新的文件要同步到各个服务器上,导致各个文件副本的修改时间不一定相同。那么当用户一次访问请求的服务器和另一次访问请求的服务器不同时,就有可能因为两个文件副本的修改时间不同而使得Last-Modified形式的协商缓存失效。

  如果这种情况采用Etag形式的协商缓存,根据文件内容而不是修改时间来判断缓存,就不会有这个问题了。

浏览器缓存注意点

  通过地址栏访问、以及强制刷新网页的时候,HTTP 请求头自动会带上Cache-Control: no-cachePragma: no-cache的信息。只要有这两个请求头之一,浏览器就会忽略响应头中的Cache-Control字段,即忽略强缓存。

强制刷新的区别

  因为强制刷新会带上Cache-Control: no-cachePragma: no-cache请求头且不会带上If-Modified-SceneIf-None-Match请求头,意思是不使用缓存,忽略缓存。

max-age = 0 和 no-cache 有啥区别

  no-cache 不进行强缓存,走协商缓存,而max-age=0是进行强缓存,但是过期了,需要更新。虽然实际上看起来两者效果是一样的。

缓存位置

 一般是缓存到内存以及硬盘

  • from memory cache 表示资源是从内存当中获取的,浏览器关闭后该资源内存会被释放。
  • from disk memory 表示资源是从硬盘中读取的,关掉浏览器资源依然在。

 

小结

  1. 浏览器能不能缓存核心是服务端端返回的响应头决定,如强缓存的标识头,协商缓存的两个标识头,整个过程主要由服务端控制;
  2. 强缓存标识符:响应头的cache-control: 不是no-store,强缓存的状态码是200,带上from memory cache/from disk memory

    协商缓存标识符:

    响应头的带有 Last-Modified表示缓存起来,下次请求带上If-Modified-Since值是上次 Last-Modified的值。

    响应头的带有 ETag表示缓存起来,下次请求带上If-None-Match值是上次 ETag的值。

    (1)如果一致说明文件内容没有发生变化,直接返回304;
    (2)如果不一致返回200 + 最新资源 + 最新的 ETag字符串。

  3. 强制刷新会HTTP 请求头自动会带上Cache-Control: no-cache和Pragma: no-cache请求头且不会带上If-Modified-SceneIf-None-Match,意思是不使用缓存,忽略缓存。

 

nodejs 架构图

Node.js的结构大致分为三个层次:

  • Node Standard Library是我们每天都在用的标准库、api,如 Http、Buffer、fs 等模块。它们都是由 JavaScript 编写的,可以通过require(..)直接能调用。
  • Node Bindings沟通 JS 和 C++ 的桥梁,封装 V8 和 Libuv 的细节,向上层提供基础API服务。这一层是支撑 Node.js 运行的关键,由 C/C++ 实现。
  • 第三层是支撑 Node.js 运行的关键,由 C/C++ 实现。

    V8是 Google 开发的 javascript 引擎,为 javascript 提供了在非浏览器端运行的环境,可以说它就是 Node.js 的发动机。它的高效是 Node.js 之所以高效的原因之一。

    Libuv为Node.js提供了跨平台,线程池,事件池,异步 I/O 等能力,是Node.js如此强大的关键。

    C-ares提供了异步处理 DNS 相关的能力。

    http_parser、OpenSSL、zlib等,提供包括 http 解析、SSL、数据压缩等其他的能力。

标签:Node,缓存,浏览器,入门,nodejs,cache,js,基本概念,请求
From: https://www.cnblogs.com/longbensong/p/17392647.html

相关文章

  • Docker入门与实战-Docker镜像的使用
    Docker入门与实战二.Docker镜像的使用1.获取镜像​ 命令:docker[image]pullimage-name[:tag]​ 说明:​ name为镜像仓库名称,严格来说,该name应该由注册服务器地址+镜像仓库名称组成,这样做可以避免不同仓库(注册服务器)下的镜像名称冲突的问 题,如果该注册服务器地......
  • Intellij Idea教程_编程入门自学教程_菜鸟教程-免费教程分享
    教程简介IDEA全称IntelliJIDEA,是java编程语言的集成开发环境。IntelliJ在业界被公认为最好的Java开发工具,尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、创新的GUI设计等方面的功能可以说是超常的。IDEA是JetBra......
  • 分数阶导数的基本概念与介绍
    重要参考华东师范大学潘建瑜教授第一讲分数阶微分方程维基百科分数微积分连接成功-知乎慢慢推导柯西重复积分公式维基百科Gamma函数以下是我的整理一、学习的思路我们熟知的是整数阶的微积分定义,分数阶微积分的定义一般就是由已知的定义推导而来的。所......
  • Flask快速入门3
    十一,FlaskCookies Cookie以文本文件的形式存储在客户端的计算机上。其目的是记住和跟踪与客户使用相关的数据,以获得更好的访问者体验和网站统计信息。 Request对象包含Cookie的属性。它是所有cookie变量及其对应值的字典对象,客户端已传输。除此之外,cookie还存储其网站的到期时间......
  • Python基础语法入门
    Python基础语法入门1、Python的注释符号1、什么是注释?#学习任何一门代码,先学注释,注释是代码之母注释就是对一段代码的解释说明,它不会参与到代码的运行,只是起到提示作用2、如何注释?2.1、#单行注释#它可以使用快捷键帮助我们把代码写的更加规范快捷键:Ctrl+alt+1(格式......
  • Vue入门浅析
    title:vue入门浅析author:Sun-Winddate:May14,2022写这篇博文的目的在于为初学vue的同学对vue有一些更进一步的了解读这篇博文前,您应该至少安装了vue环境,能在本地运行一个简单的demo本文将浅析vue项目工程的结构,以及用npm运行项目的过程中发生的一些事件注明:该文本应在......
  • 1、基础入门
    一、域名什么是域名?域名在哪里注册?什么是二级域名?以及多级域名?域名发现对于安全的意义?答:(1)域名是由一串用点分割的名字组成的internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位。(2)域名注册(3)什么是二级域名?分为国际二级域名和国家二级......
  • IO多路复用基本概念:select,epoll(转)
    原文:https://blog.csdn.net/weixin_45743893/article/details/122970342IO多路复用概念IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。其实就是在单个线程中通过记录跟踪每一个I/O流的状态来管理多个I/O流。它们三的作用提供一种IO复用的方式......
  • FEniCSx入门——解Poisson方程
    一、Poisson方程 可转换为线性弱形式 其中,u:trialfunction是近似解v:testfunction是Poisson方程两边同乘的函数,用于转换为弱形式。 在Fenics中解PDE时,必须进行下面几个步骤:1、将PDE问题转换成离散变分问题:即寻找u∈V,使得 2、选择V和V_hat空间,换句话说就是......
  • 数据结构与算法之一道题感受算法(算法入门)
    题目:给定N个整数的序列{A1,A2,....An},求函数F(i,j)=Max{Ai+.....Aj }题目要求:这道题的目的是要求给定的一个整数序列中,它所含的连续子序列的最大值,比如现在我有一个整数序列{-3,2,3,-3,1}它的最大子序列很显然是 {2,3}第一种方法蛮力法(强制枚举):我们从第一个整数开始遍历,依......