NodeJS

  1. NodeJS
    1. 简介
    2. nvm
    3. npm
    4. 搭建简单服务
      1. 启动服务器
      2. JS中的API
      3. Fetch API
        1. 跨域访问问题
    5. JS模块的导入和导出

NodeJS

简介

Node.js 就是运行在服务端的 JavaScript, 是一个基于 Chrome JavaScript 运行时建立的一个平台

Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常快,性能非常好

前端开发的时候也需要有一个自己的服务器,这里我们选择node.js

nvm

nvm即(node version manager),好处是方便切换node.js版本

安装注意事项

设置国内镜像地址

nvm node_mirror http://npm.taobao.org/mirrors/node/
nvm npm_mirror https://npm.taobao.org/mirrors/npm/

查看可用node版本

nvm list available

切换node版本(需要管理员权限)

nvm use 16.15.0

npm

npm是js的包管理器,类似于java的maven,要确保它使用的是国内镜像

检查镜像

npm get registry

如果返回的不是https://registry.npm.taobao.org/,需要做如下设置

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

搭建简单服务

新建一个项目文件夹,当前目录下cmd执行npm指令,添加一个依赖,这里使用express框架

VScode打开控制台快捷键ctrl+shift+`

npm install express --save-dev

package.json文件

类似于java中的pom.xml文件

启动服务器

编写启动express服务器的代码,这里我们选用VSCode编辑器开发

修改package.json文件,添加module支持import语法

{
  "type":"module",
  "devDependencies": {
    "express": "^4.18.1"
  }
}
  • 其中的devDependencies是npm install --save-dev添加的

编写main.js代码

import express from 'express'
const app = express();

app.use(express.static('./'));
app.listen(7070);

执行js代码(运行前端服务器),在工程目录下启动

node main.js

指定静态资源

这里指定当前目录为静态资源目录

app.use(express.static('./'))

在当前目录创建一个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>
<link rel="stylesheet" href="./style.css">
<body>
    <div class="title">学生列表</div>
    <div class="thead">
        <div class="row bold">
            <div class="col">编号</div>
            <div class="col">姓名</div>
            <div class="col">性别</div>
            <div class="col">年龄</div>
        </div>
    </div>
    <div class="tbody">

    </div>

    <template id="tp">
        <div class="row">
            <div class="col">xx</div>
            <div class="col">xx</div>
            <div class="col">xx</div>
            <div class="col">xx</div>
        </div>
    </template>

</body>
</html>

JS中的API

通过选择器查找单个元素

**querySelector(‘.col’)**通过类col查找单个元素

document.querySelector('.col');

通过选择器查找多个元素

**querySelectorAll(‘.col’)**通过类col查找到多个元素

document.querySelector('.thead').querySelectorAll('.col');

通过template标签生成学生列表

<template id="tp">
    <div class="row">
        <div class="col">xx</div>
        <div class="col">xx</div>
        <div class="col">xx</div>
        <div class="col">xx</div>
    </div>
</template>

js动态生成

importNode函数 用于复制元素

  • 参数1:元素变量
  • 参数2:是否复制子元素
 //假设这是后端传来的数据
let array = [
    {id: 1,name: "张三",sex: "男", age:18},
    {id: 2,name: "李四",sex: "女", age:17}
];

document.getElementById("tp");

//获取模板的内容属性
const row = tp.content;

const [c1,c2,c3,c4] = row.querySelectorAll(".col");

const tbody = document.querySelector('.tbody');

for(const obj of array){
    c1.textContent = obj.id;
    c2.textContent = obj.name;
    c3.textContent = obj.sex;
    c4.textContent = obj.age;
    //拷贝元素
    const newNode = document.importNode(row,true);
    //添加子元素
    tbody.appendChild(newNode);
}

Fetch API

Fetch API 可以用来获取远程数据,它有两种方式接收结果,同步方式和异步方式

格式:

fetch(url,options) //返回 Promise对象

同步方式

const ans = await fetch(url,options)
//后续代码
  • await 关键字必须在一个标记了async的function内来使用
  • 后续代码不会再结果返回前执行

代码示例:

 async function findStu(){
        //获得了一个响应对象
        const response = await fetch('students.json');

        //获取响应体,将json格式数据转化为js数组
        const array = await response.json();

        const tp = document.getElementById("tp");

        //获取模板的内容属性
        const row = tp.content;

        const [c1,c2,c3,c4] = row.querySelectorAll(".col");

        const tbody = document.querySelector('.tbody');

        for(const obj of array){
            c1.textContent = obj.id;
            c2.textContent = obj.name;
            c3.textContent = obj.sex;
            c4.textContent = obj.age;
            //拷贝元素
            const newNode = document.importNode(row,true);
            //添加子元素
            tbody.appendChild(newNode);
        }
    }

    findStu();

异步方式

fetch(url,options).then(ans =>{...})
//后续代码
  • 后续代码不必等待结果返回就可以执行

代码示例:

//获得了一个响应对象
fetch('students.json').then(response => response.json()).then(array =>{

    const tp = document.getElementById("tp");

    //获取模板的内容属性
    const row = tp.content;

    const [c1,c2,c3,c4] = row.querySelectorAll(".col");

    const tbody = document.querySelector('.tbody');

    for(const obj of array){
        c1.textContent = obj.id;
        c2.textContent = obj.name;
        c3.textContent = obj.sex;
        c4.textContent = obj.age;
        //拷贝元素
        const newNode = document.importNode(row,true);
        //添加子元素
        tbody.appendChild(newNode);
    }

});

跨域访问问题

Fetch访问后端资源,使用请求头的方式解决跨域问题

这里区别于之前访问前端服务器资源,会发生跨域访问问题

只要协议、主机、端口号之一不同,就不同源

  • 浏览器会对访问进行同源检查,如果同源则数据可用
  • 一般会由前端服务器携带请求的来源信息Origin:http://localhost:7070
  • 后端服务器接收到来源信息后进行判断是否通过检查,通过则返回一个响应信息Access-Control-Allow-Origin:http://localhost:7070
fetch("http://localhost:8080/student/list")

后端加上**@CrossOrigin注解**

  • 注明哪些请求来源通过检查
@RestController
@RequestMapping("student")
public class TestController {

    @Autowired
    private StudentService studentService;

    @RequestMapping("list")
    @CrossOrigin("http://localhost:7070")
    public List<Student> test(){

        List<Student> studentList = studentService.getStudentList();

        return studentList;

    }

}

同源检查时浏览器的行为,而且只针对fetch、xhr请求

  • 如果是其它客户端,例如java http client,postman,它们是不会做同源检查的
  • 通过表单提交,浏览器直接输入url地址这些方式发送的请求,也不会做同源检查

使用代理服务器解决跨域访问问题

一般通过/api/前缀来区分是代理请求还是直接请求

代理服务器中会通过JavaSript的Api向后端服务器发起请求获取数据

这里不使用浏览器的API直接访问tomcat服务器,相当于把请求全部发送给前端express服务器,通过前端服务器的jsAPI发起请求向后端服务器请求数据,这样就不会发生浏览器的跨域访问问题

安装代理服务器插件

注意需要在工程目录下运行cmd

npm install http-proxy-middleware --save-dev

在express 服务器启动代码中加入

import {createProxyMiddleware} from 'http-proxy-middleware'

app.use('/api',createProxyMiddleware({
    target:'http://localhost:8080',
    //重写接口路由
    pathRewrite:{'^/api':''},
    changeOrigin:true}));

//...

如果当实际需要请求的路径里面没有”/api“时. 就需要 pathRewrite,用’’^/api’’:’’, 把’/api’去掉

JS模块的导入和导出

import必须遵循同源策略,src引用js的方式可以不同源

单个导出

export 需要导出的数据

//单个导出
export const a = 10;
export let b = 20;
export function c(){
    alert("c");
}

一齐导出

const a = 10;
let b = 20;
function c(){
    alert("c");
}

//一齐导出
export {a,b,c}

导入

需要在script元素中添加type属性为module

import 需要导入的数据 from 'js文件路径'

<script type="module">
    import {a,b,c} from './myJS.js'
    alert(a);
    alert(b);
    c();
</script>

导出默认

//带有default的只能出现一个
export default b;

//export default c; 例如这条如果也是default就会报错

默认导入

//导入默认的名字可以随便起,这里的x其实就是b
import x from './myJS.js'

整体导入

//需要用as给模块起名字
import * as m from './myJS.js'
//使用m.c(); 可以调用模块中的函数

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com

文章标题:NodeJS

字数:2.1k

本文作者:Os467

发布时间:2022-09-08, 20:18:43

最后更新:2022-09-08, 20:19:46

原始链接:https://os467.github.io/2022/09/08/NodeJS/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏