Node.js 就是运行在服务端的 JavaScript, 是一个基于 Chrome JavaScript 运行时建立的一个平台
Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常快,性能非常好
前端开发的时候也需要有一个自己的服务器,这里我们选择node.js
nvm即(node version manager),好处是方便切换node.js版本
安装注意事项
设置国内镜像地址
1nvm node_mirror http://npm.taobao.org/mirrors/node/
2nvm npm_mirror https://npm.taobao.org/mirrors/npm/
查看可用node版本
xxxxxxxxxx
11nvm list available
切换node版本(需要管理员权限)
xxxxxxxxxx
11nvm use 16.15.0
npm是js的包管理器,类似于java的maven,要确保它使用的是国内镜像
检查镜像
xxxxxxxxxx
11npm get registry
如果返回的不是https://registry.npm.taobao.org/
,需要做如下设置
xxxxxxxxxx
11npm config set registry https://registry.npm.taobao.org/
新建一个项目文件夹,当前目录下cmd执行npm指令,添加一个依赖,这里使用express框架
VScode打开控制台快捷键ctrl+shift+`
xxxxxxxxxx
11npm install express --save-dev
package.json文件
类似于java中的pom.xml文件
编写启动express服务器的代码,这里我们选用VSCode编辑器开发
修改package.json文件,添加module支持import语法
xxxxxxxxxx
61{
2 "type":"module",
3 "devDependencies": {
4 "express": "^4.18.1"
5 }
6}
npm install --save-dev
添加的
编写main.js代码
x1import express from 'express'
2const app = express();
3
4app.use(express.static('./'));
5app.listen(7070);
执行js代码(运行前端服务器),在工程目录下启动
xxxxxxxxxx
11node main.js
指定静态资源
这里指定当前目录为静态资源目录
xxxxxxxxxx
11app.use(express.static('./'))
在当前目录创建一个index.html文件,进行前端服务器测试
xxxxxxxxxx
341
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>学生列表</title>
8</head>
9<link rel="stylesheet" href="./style.css">
10<body>
11 <div class="title">学生列表</div>
12 <div class="thead">
13 <div class="row bold">
14 <div class="col">编号</div>
15 <div class="col">姓名</div>
16 <div class="col">性别</div>
17 <div class="col">年龄</div>
18 </div>
19 </div>
20 <div class="tbody">
21
22 </div>
23
24 <template id="tp">
25 <div class="row">
26 <div class="col">xx</div>
27 <div class="col">xx</div>
28 <div class="col">xx</div>
29 <div class="col">xx</div>
30 </div>
31 </template>
32
33</body>
34</html>
通过选择器查找单个元素
querySelector('.col')通过类col
查找单个元素
xxxxxxxxxx
11document.querySelector('.col');
通过选择器查找多个元素
querySelectorAll('.col')通过类col
查找到多个元素
xxxxxxxxxx
11document.querySelector('.thead').querySelectorAll('.col');
通过template标签生成学生列表
xxxxxxxxxx
81<template id="tp">
2 <div class="row">
3 <div class="col">xx</div>
4 <div class="col">xx</div>
5 <div class="col">xx</div>
6 <div class="col">xx</div>
7 </div>
8</template>
js动态生成
importNode函数 用于复制元素
xxxxxxxxxx
251 //假设这是后端传来的数据
2let array = [
3 {id: 1,name: "张三",sex: "男", age:18},
4 {id: 2,name: "李四",sex: "女", age:17}
5];
6
7document.getElementById("tp");
8
9//获取模板的内容属性
10const row = tp.content;
11
12const [c1,c2,c3,c4] = row.querySelectorAll(".col");
13
14const tbody = document.querySelector('.tbody');
15
16for(const obj of array){
17 c1.textContent = obj.id;
18 c2.textContent = obj.name;
19 c3.textContent = obj.sex;
20 c4.textContent = obj.age;
21 //拷贝元素
22 const newNode = document.importNode(row,true);
23 //添加子元素
24 tbody.appendChild(newNode);
25}
Fetch API 可以用来获取远程数据,它有两种方式接收结果,同步方式和异步方式
格式:
xxxxxxxxxx
11fetch(url,options) //返回 Promise对象
同步方式
xxxxxxxxxx
21const ans = await fetch(url,options)
2//后续代码
代码示例:
xxxxxxxxxx
291 async function findStu(){
2 //获得了一个响应对象
3 const response = await fetch('students.json');
4
5 //获取响应体,将json格式数据转化为js数组
6 const array = await response.json();
7
8 const tp = document.getElementById("tp");
9
10 //获取模板的内容属性
11 const row = tp.content;
12
13 const [c1,c2,c3,c4] = row.querySelectorAll(".col");
14
15 const tbody = document.querySelector('.tbody');
16
17 for(const obj of array){
18 c1.textContent = obj.id;
19 c2.textContent = obj.name;
20 c3.textContent = obj.sex;
21 c4.textContent = obj.age;
22 //拷贝元素
23 const newNode = document.importNode(row,true);
24 //添加子元素
25 tbody.appendChild(newNode);
26 }
27 }
28
29 findStu();
异步方式
xxxxxxxxxx
21fetch(url,options).then(ans =>{ })
2//后续代码
代码示例:
xxxxxxxxxx
241//获得了一个响应对象
2fetch('students.json').then(response => response.json()).then(array =>{
3
4 const tp = document.getElementById("tp");
5
6 //获取模板的内容属性
7 const row = tp.content;
8
9 const [c1,c2,c3,c4] = row.querySelectorAll(".col");
10
11 const tbody = document.querySelector('.tbody');
12
13 for(const obj of array){
14 c1.textContent = obj.id;
15 c2.textContent = obj.name;
16 c3.textContent = obj.sex;
17 c4.textContent = obj.age;
18 //拷贝元素
19 const newNode = document.importNode(row,true);
20 //添加子元素
21 tbody.appendChild(newNode);
22 }
23
24});
Fetch访问后端资源,使用请求头的方式解决跨域问题
这里区别于之前访问前端服务器资源,会发生跨域访问问题
只要协议、主机、端口号之一不同,就不同源
Origin:http://localhost:7070
Access-Control-Allow-Origin:http://localhost:7070
xxxxxxxxxx
11fetch("http://localhost:8080/student/list")
后端加上@CrossOrigin注解
xxxxxxxxxx
181
2"student") (
3public class TestController {
4
5
6 private StudentService studentService;
7
8 "list") (
9 "http://localhost:7070") (
10 public List<Student> test(){
11
12 List<Student> studentList = studentService.getStudentList();
13
14 return studentList;
15
16 }
17
18}
同源检查时浏览器的行为,而且只针对fetch、xhr请求
- 如果是其它客户端,例如java http client,postman,它们是不会做同源检查的
- 通过表单提交,浏览器直接输入url地址这些方式发送的请求,也不会做同源检查
使用代理服务器解决跨域访问问题
一般通过/api/
前缀来区分是代理请求
还是直接请求
代理服务器中会通过JavaSript的Api向后端服务器发起请求获取数据
这里不使用浏览器的API直接访问tomcat服务器,相当于把请求全部发送给前端express服务器,通过前端服务器的jsAPI发起请求向后端服务器请求数据,这样就不会发生浏览器的跨域访问问题
安装代理服务器插件
注意需要在工程目录下运行cmd
xxxxxxxxxx
11npm install http-proxy-middleware --save-dev
在express 服务器启动代码中加入
xxxxxxxxxx
91import {createProxyMiddleware} from 'http-proxy-middleware'
2
3app.use('/api',createProxyMiddleware({
4 target:'http://localhost:8080',
5 //重写接口路由
6 pathRewrite:{'^/api':''},
7 changeOrigin:true}));
8
9//...
如果当实际需要请求的路径里面没有”/api“时. 就需要 pathRewrite,用’’^/api’’:’’, 把’/api’去掉
import必须遵循同源策略,src引用js的方式可以不同源
单个导出
export
需要导出的数据
xxxxxxxxxx
61//单个导出
2export const a = 10;
3export let b = 20;
4export function c(){
5 alert("c");
6}
一齐导出
xxxxxxxxxx
81const a = 10;
2let b = 20;
3function c(){
4 alert("c");
5}
6
7//一齐导出
8export {a,b,c}
导入
需要在script元素中添加type属性为module
import
需要导入的数据 from
'js文件路径'
xxxxxxxxxx
61<script type="module">
2 import {a,b,c} from './myJS.js'
3 alert(a);
4 alert(b);
5 c();
6</script>
导出默认
xxxxxxxxxx
41//带有default的只能出现一个
2export default b;
3
4//export default c; 例如这条如果也是default就会报错
默认导入
xxxxxxxxxx
21//导入默认的名字可以随便起,这里的x其实就是b
2import x from './myJS.js'
整体导入
xxxxxxxxxx
31//需要用as给模块起名字
2import * as m from './myJS.js'
3//使用m.c(); 可以调用模块中的函数