前端 | 青训营笔记

69 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的的第4天

Nodejs 基础

1. 概念

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时。

Chrome V8 引擎

浏览器的内核主要分为两类:

  1. 渲染引擎:负责解析和编译 HTML + CSS 代码;
  2. JS 引擎:负责解析和编译 JavaScript 代码;

Chrome V8 引擎,是谷歌浏览器厂商开发的一款 JS 引擎,是现在公认的解析 JS 代码效率最快的引擎。

JavaScript 运行时

运行时,指的就是“运行环境”。

因为 Nodejs 中引入了 JS 引擎,所以在 Nodejs 中可以运行 JavaScript 代码,换句话说 ,Nodejs 是 JavaScript 代码的运行环境。

Nodejs 中运行 JS 代码

在终端中通过以下命令可以运行一个 JS 文件:

# node 文件名
node hello.js

注意,在运行上述命令时,需要注意当前终端所在路径,如果路径不对,会出现报错:

更改终端路径

  • 可以在 VSCode 中直接通过右键对应的 JS 文件,然后选择【在终端中运行】,即可定位到对应路径;
  • 还可以通过 cd 来跟上文件名或者文件路径,来进行终端路径的切换;
  • 还可以通过 cd .. 来返回上一级路径;

快捷键

  • 键盘上下箭头可以查找终端命令的历史记录;

  • 键盘 tab 键可以在终端自动补全文件名;

npm

npm,包管理器。它是随着 Node.js 安装时一并安装好的,不需要单独安装。

通过 npm -v 来查看对应的版本号。

作用

  1. 用户可以从 npm 服务器上去下载别人上传到第三方代码;
  2. 用户可以将自己写的代码上传到 npm 服务器上;

使用

设置淘宝镜像

npm config set registry https://registry.npm.taobao.org

下载

  1. 局部下载,指将指定包下载到当前项目所在根目录:
npm install 包名称
# 简写
npm i 包名称
  1. 全局下载,指将指定包下载到了 C 盘中:
npm i -g 包名称
  1. 根据 package.json 下载
npm i 

卸载

npm uninstall 包名称
npm uninstall -g 包名称

package.json

在项目根目录执行 npm init 或者 npm init -y 命令对项目进行初始化,生成 package.json 文件。

跨域

“域”,可以理解通过访问或请求的地址。域的组成包括以下几个部分:

  • 协议:http、https
  • IP
  • 端口号
http://www.woniuxy.com/tc
协议 + IP + 端口号

同源策略

同源策略,是浏览器端的一个安全策略。该策略要求:当我们在一个源(域)中,向另一个源(域)发起请求时,两个源之间的协议、IP、端口三者必须一致,则为同源。

如果协议、IP、端口三者中,有一个不一致,则为行为跨域。浏览器在默认情况下,是不允许跨域的。一旦跨域,浏览器就会出现以下报错:

跨域的解决方案

1. JSONP

前端在 jQuery 的 ajax 中添加一个 dataType 属性,值为 jsonp

$.ajax({
    url: 'http://localhost:3000/students/getStudents',
    type: 'get',
    dataType: 'jsonp',
    success(msg) {

    }
})

在 Nodejs 的后端,将 res.send() 改成 res.jsonp()

router.get('/getStudents', async function (req, res) {
    const data = await getStudents(req.query);
    res.jsonp(data);
})

缺点:JSONP 的方式只能处理 GET 请求类型的跨域。

原理:在 HTML 中,<script><img><link> 是天生就支持跨域的,JSONP 的原理就是利用了 <script> 标签来实现的 ajax 数据获取。

2. CORS

CORS 解决跨域的方式,是在服务端进行设置:

var allowCrossDomain = function (req, res, next) {
    // 设置允许哪一个源(域)可以进行跨域访问,* 表示所有源
    res.header("Access-Control-Allow-Origin", "*");
    // 设置允许跨域访问的请求头
    res.header("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept,Authorization");
    // 设置允许跨域访问的请求类型
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    // 设置允许 cookie 发送到服务器 
    res.header('Access-Control-Allow-Credentials', 'true');
    next();
};
app.use(allowCrossDomain); // 使用该中间件

3. 代理服务器(Node 中间层)

转发请求

前端发送 ajax 请求到代理服务器,代理服务器需要将该请求再转发到目标服务器,转发的方式分为两种:

  1. 请求到达代理服务器后,直接转发至目标服务器;
  2. 请求到达代理服务器后,在代理服务器中进行额外的操作(例如:数据加密),然后再将请求转发至目标服务器;

直接转发

先下载需要用到的依赖包 http-proxy-middleware

npm i http-proxy-middleware --save

请求转发的相关配置:

const options = {
    target: 'http://localhost:3000', // 目标服务器的地址
    changeOrigin: true,
    pathRewrite: {// /api/users/login
        '^/api': '/'
    }
}

将以上配置应用到服务器中:

const { createProxyMiddleware } = require('http-proxy-middleware');

const options = {
    target: 'http://localhost:3000', // 目标服务器的地址
    changeOrigin: true,
    pathRewrite: {// /api/users/login
        '^/api': '/'
    }
}

app.use('/api', createProxyMiddleware(options));

以上配置完成后,前端在发送 ajax 请求时,所有需要直接转发走的请求 ,URL 前面都要加上 /api

间接转发

下载:

npm i request-promise request --save

前端发送请求时,URL 不需要加 /api,我们让请求进入到代理服务器的第一层表现层。

接下来我们就可以在表现层中做自己的一些额外处理的操作,操作完成后,再通过以下代码将请求转发到目标服务器:

const rp = require('request-promise');

const data = await rp({
    uri: 'http://localhost:3000/users/login',   // 目标服务器的接口地址
    method: 'post',  // 请求类型
    body: { username, password },  // 参数
    json: true  // 数据传输的格式为 json 格式
});
console.log(data);
res.send(data);

data 接收到的就是目标服务器 res.send() 的结果,然后在代理服务器,我们可以对 data 再进行处理,最后再通过 res.send() 返回给前端。