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