如何写一个网站(做网站所需的知识点的整理:Spring Boot+MyBatis Plus+Vue+Nginx+vps)

概述:

涉及到的技术:

后端:Spring Boot + MyBatis Plus
前端:Vue + ElementUI + axios
数据库:MySQL
服务器:ubuntu

一、后端

1、在 IntellJ IDEA 搭建一个spring Boot构建的工程

构建:

在这里插入图片描述
在这里插入图片描述
文件结构:
在这里插入图片描述
pox.xm文件:
在这里插入图片描述

2、写给http请求的响应:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3、写拦截器:

在这里插入图片描述

4、使用MyBatisPlus|MyBatis 对MySQL 进行操作

在这里插入图片描述

依赖需要写在pom.xml中的 标签下:

        <!--MyBatisPlus依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!--mysql驱动依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.20</version>
        </dependency>

5、配置Maven

在这里插入图片描述
配置文件需要添加的内容:

  <localRepository>D:\mvn\repo</localRepository>


<mirror>
	<id>aliyunmaven</id>
	<mirrorOf>*</mirrorOf>
	<name>阿里云公共仓库</name>
	<url>https://maven.aliyun.com/repository/public</url>
</mirror>

6、JWT跨域认证

说明:

JSON Web Token:将用户信息放到用户自己浏览器上,实现登录后的用户身份验证(一种手段)。

Token 通常包括三个部分:头部(Header)、有效负载(Payload)和签名(Signature)。
头部包含有关 Token 的元信息,
有效负载包含有关用户或其他主题的信息,
签名则用于验证 Token 的完整性。

例如:
“eyJ0eXBlIjoiSldUIiwiYWxnIjoiSFM1MTIifQ.
eyJzdWIiOiJBQkNVc2VyIiwiaWF0IjoxNzAwMDMwNDYwLCJleHAiOjE3MDA2MzUyNjB9.
k7M4UqeOia255NgUo-ECk-VP4mm4tzEjv253edvXYxWDpuHbbPH_skpTAVV1wmX1MGIKx4lPMU6OpBK7IgUKjw”

他们用点隔开,头部、有效荷载没有加密,签名使用了非对称加密和哈希算法。使用非对称加密是为了让有公钥的人来验证,使用哈希是为了优化性能。

使用:token分为三个部分

在这里插入图片描述
使用:
下面使用 HS512(HMAC SHA-512)是对称加密(密钥用的是一个)。
在这里插入图片描述
(依赖)

在这里插入图片描述
(使用)

7、加盐加密

过程:在这里插入图片描述

使用:

在这里插入图片描述

8、返回static目录下的html文件的写法(不修改内容)

在请求中获取:

package com.example.mddemo.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

@Controller
@RequestMapping("/o")
public class OtherController {

    private final ResourceLoader resourceLoader;

    public OtherController(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @GetMapping("/showHtml")
    @ResponseBody
    public String showHtml() {
        // 通过 ResourceLoader 加载静态文件
        Resource resource = resourceLoader.getResource("classpath:/static/index.html");

        // 将文件内容放入 Model 中,供 Thymeleaf 或其他模板引擎渲染
        ///model.addAttribute("htmlContent", resource);

        // 返回视图名称,这里假设使用 Thymeleaf 模板引擎
        return readHtmlContent(resource);
    }

    private String readHtmlContent(Resource resource) {
        try (InputStream inputStream = resource.getInputStream()) {
            // 传统的方式读取输入流
            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            return result.toString(StandardCharsets.UTF_8.name());
        } catch (IOException e) {
            // 处理异常
            e.printStackTrace();
            return "Error reading HTML content";
        }
    }
}

9、设置cookie(设置后浏览器后面的请求都会发送这个 cookie)

第一种方式:

package com.example.mddemo.controller;

import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

@RestController
public class SetHeadController {

    @GetMapping("/set-cookie")
    public String setCookie(HttpServletResponse response) {
        // 创建一个 Cookie 对象
        Cookie cookie = new Cookie("myToken", "yourToken");

        // 设置 Cookie 的属性
        cookie.setPath("/"); // Cookie 在所有路径下都有效
        cookie.setHttpOnly(true); // 令 Cookie 不可通过 JavaScript 访问
        //cookie.setSecure(true); // 仅在 HTTPS 连接时发送

        // 将 Cookie 添加到响应头
        response.addCookie(cookie);

        return "Cookie set successfully!";
    }

    @GetMapping("/get-cookie")
    public String getCookie(@CookieValue(name = "myToken", defaultValue = "defaultToken") String myToken) {
        // 在这里,myToken 参数将包含从请求中提取的名为 "myToken" 的 Cookie 的值
        return "Cookie value: " + myToken;
    }

    // 其他处理器方法...
}

第二种方式:
在拦截器中获取:
(拦截器类)

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前执行,可以用来获取 Cookie 的值
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("myToken".equals(cookie.getName())) {
                    String tokenValue = cookie.getValue();
                    // 在这里处理获取到的 tokenValue
                    System.out.println("Token value from interceptor: " + tokenValue);
                    break;
                }
            }
        }

        return true; // 返回 true 表示继续处理请求,返回 false 表示中断请求处理
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 在请求处理之后,视图渲染之前执行
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在请求处理完成后执行,即在视图渲染之后执行
    }
}

(设置类:)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public MyInterceptor myInterceptor() {
        return new MyInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册拦截器并指定拦截的路径
        registry.addInterceptor(myInterceptor()).addPathPatterns("/**");
    }
}

二、前端

1、Vue 一些基本语法

(1).基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--1、导入 vue的脚本文件-->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <!--2、声明要被 vue 所控制的 DOM 区域-->
    <div id="app">
        {{message}}
    </div>

    <!--3、创建 vue 的实例对象-->
    <script>
        const hello = {
            //指定数据源,即MVVM中的Model1
            data: function(){
                return {
                    message:"Hello Vue ! "
                }
            }
        }
        const app = Vue.createApp(hello)
        app.mount('#app')
    </script>
</body>
</html>

(2).内容渲染指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--1、导入 vue的脚本文件-->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <!--2、声明要被 vue 所控制的 DOM 区域-->
    <div id="app">
        <p>姓名:{{username}}</p>
        <p>性别:{{gender}}</p>

        <p>{{desc}}</p>
        <p v-html="desc"></p>
    </div>

    <!--3、创建 vue 的实例对象-->
    <script>
        const vm = {
            //指定数据源,即MVVM中的Model1
            data: function(){
                return {
                    username:'YW',
                    gender:'女',
                    desc:'<a href="http://www.baidu.com">百度</a>'
                }
            }
        }
        const app = Vue.createApp(vm)
        app.mount('#app')
    </script>
</body>
</html>

(3).属性绑定指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--1、导入 vue的脚本文件-->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <!--2、声明要被 vue 所控制的 DOM 区域-->
    <div id="app">
        <a :href="link">百度</a>
        <input type="text" :placeholder="inputValue">
        <img :src="imSrc" :style="{width:w}" alt="">
    </div>

    <!--3、创建 vue 的实例对象-->
    <script>
        const vm = {
            //指定数据源,即MVVM中的Model1
            data: function(){
                return {
                    link:"http://www.baidu.com",
                    //文本框的占位符内容
                    inputValue: '请输入内容',
                    //图片的 src 地址
                    imSrc:'./image/apple.png',
                    w:'500px'
                }
            }
        }
        const app = Vue.createApp(vm)
        app.mount('#app')
    </script>
</body>
</html>

(4).使用JavaScrip表达式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--1、导入 vue的脚本文件-->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <!--2、声明要被 vue 所控制的 DOM 区域-->
    <div id="app">
        <p>{{number + 1}}</p>
        <p>{{ok ? 'True' : 'False'}}</p>
        <p>{{message.split('').reverse().join('')}}</p>
        <p :id="'list-' + id">xxx</p>
        <p>{{user.name}}</p>
    </div>

    <!--3、创建 vue 的实例对象-->
    <script>
        const vm = {
            //指定数据源,即MVVM中的Model1
            data: function(){
                return {
                    number: 9,
                    ok: false,
                    message: 'ABC',
                    id: 3,
                    user: {
                        name: 'zs',
                    }
                }
            }
        }
        const app = Vue.createApp(vm)
        app.mount('#app')
    </script>
</body>
</html>

(5).事件绑定指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--1、导入 vue的脚本文件-->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <!--2、声明要被 vue 所控制的 DOM 区域-->
    <div id="app">
        <h3>count 的值为:{{count}}</h3>
        <button v-on:click="addCount">+1</button>
        <button @click="count-=1">-1</button>
    </div>

    <!--3、创建 vue 的实例对象-->
    <script>
        const vm = {
            //指定数据源,即MVVM中的Model1
            data: function(){
                return {
                    count:0,
                }
            },
            methods:{
                addCount(){
                    this.count+=1
                }
            }
        }
        const app = Vue.createApp(vm)
        app.mount('#app')
    </script>
</body>
</html>

(6).条件渲染指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--1、导入 vue的脚本文件-->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <!--2、声明要被 vue 所控制的 DOM 区域-->
    <!-- 两种绑定方法的方式 
        on开头的用 @来绑定-->
    <div id="app">
        <button @click="flag = !flag">Toggle Flag</button>

        <p v-if="flag">S v-if</p>
        <p v-show="flag">U v-show</p>
    </div>

    <!--3、创建 vue 的实例对象-->
    <script>
        const vm = {
            //指定数据源,即MVVM中的Model1
            data: function(){
                return {
                    flag: false,
                }
            }
        }
        const app = Vue.createApp(vm)
        app.mount('#app')
    </script>
</body>
</html>

(7).v-else和v-else-if指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--1、导入 vue的脚本文件-->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <!--2、声明要被 vue 所控制的 DOM 区域-->
    <!-- 两种绑定方法的方式 
        on开头的用 @来绑定-->
    <div id="app">
        <p v-if="num>0.5">随机数 > 0.5</p>
        <p v-else>随机数 小于等于 0.5</p>
        <hr />
        <p v-if="type === 'A'">优秀</p>
        <p v-else-if="type === 'B'">良好</p>
        <p v-else-if="type === 'C'">一般</p>
        <p v-else></p>

        <div v-show="a">
            测试
        </div>
        <button @click="a=!a">点击</button>
    </div>
    <!--3、创建 vue 的实例对象-->
    <script>
        const vm = {
            //指定数据源,即MVVM中的Model1
            data: function(){
                return {
                    //生成 1 以内的随机数
                    num: Math.random(),
                    type: 'B',
                    a: false
                }
            }
        }
        const app = Vue.createApp(vm)
        app.mount('#app')
        app.mount('#a')
        
    </script>
</body>
</html>

(8).列表渲染指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--1、导入 vue的脚本文件-->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <!--2、声明要被 vue 所控制的 DOM 区域-->
    <div id="app">
        <ul>
            <li v-for="(user,i) in userList">索引是:{{i}},姓名是:{{user.name}}</li>
        </ul>
    </div>
    <!--3、创建 vue 的实例对象-->
    <script>
        const vm = {
            //指定数据源,即MVVM中的Model1
            data: function(){
                return {
                    userList:[
                        {id: 1, name: 'zhangsan'},
                        {id: 2, name: 'lisi'},
                        {id: 3, name: 'wangwu'},
                    ],
                }
            },
        }
        const app = Vue.createApp(vm)
        app.mount('#app')
        app.mount('#a')
        
    </script>
</body>
</html>

(9).v-for中的key.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--1、导入 vue的脚本文件-->
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <!--2、声明要被 vue 所控制的 DOM 区域-->
    <div id="app">
        <!-- 添加用户的区域 -->
		<input type="text" v-model="name">
		<button @click="addNewUser">添加</button>
		
		<!-- 用户列表区域 -->
		<ul>
			<li v-for="(user,i) in userList" :key=user.id>
				<input type="checkbox"/>
				姓名:{{user.name}}
			</li>
		</ul>
    </div>
    <!--3、创建 vue 的实例对象-->
    <script>
        const vm = {
            //指定数据源,即MVVM中的Model1
            data: function(){
                return {
                    userList: [
                        {id: 1, name: 'zhangsan'},
                        {id: 2, name: 'lisi'}
                    ],
					name: '',
					nextId: 3
                }
            },
			methods: {
				//点击了添加按钮
				addNewUser(){
					this.userList.unshift({ id: this.nextId, name: this.name })
					this.name = ''
					this.nextId++
				}
			}
        }
        const app = Vue.createApp(vm)
        app.mount('#app')
        
    </script>
</body>
</html>

2、Vue 组件化开发

下载node.js、npm、VSCode
创建vue项目:
在这里插入图片描述
Vue项目的文件结构:
在这里插入图片描述

Vue2的启动写法:
在这里插入图片描述
启动服务器:
在这里插入图片描述
一个组件的使用案例:
在这里插入图片描述

3、 ElementUI 的使用

网址:
https://element.eleme.cn/

需要的准备:

(1)、下载:终端输入
npm install element-ui
(2)、引入
在这里插入图片描述

之后可以将其网址中的代码复制到项目中,进行修改、使用。

4、 axios的使用

(1)、下载:终端输入
npm install axios
(2)、引入:
import axios from ‘axios’;

在这里插入图片描述
后端需要进行的设置:
在这里插入图片描述

5、 解决跨域问题(浏览器同源策略)

1、判断是否跨域
在这里插入图片描述
2、发送过程:(对标签的限制会小,比起ajax)
在这里插入图片描述
3、解决方法–(1)Proxy 通过访问代理服务器
在这里插入图片描述

3、解决方法–(1)CORS 服务器返回符合浏览器CORS要求规则的响应
CORS是浏览器的校验规则,有些旧的浏览器不支持 (怎么就安全了)
在这里插入图片描述

3、解决方法–(1)JSONP (json with padding)
古老的策略;
通过浏览器对标签的限制小,来添加 script 标签来完成;
scrip 的 str 只能进行 get请求;

三、打包及生产环境的搭建

1、打jar包、运行

1、配置

在这里插入图片描述

2、打包

在这里插入图片描述

3、启动

直接启动:
java -jar mddemo-0.0.1-SNAPSHOT.jar

一直运行,日志输出到 logName.log 里:
nohup java -jar mddemo-0.0.1-SNAPSHOT.jar > logName.log 2>&1 &
在这里插入图片描述

2、Vue项目的打包、运行

1、配置

在这里插入图片描述

在这里插入图片描述

2、打包

在这里插入图片描述

3、安装启动nginx,并放置 dist 包

下载:
sudo apt update //更新
sudo apt install nginx

修改default文件:
cd /etc/nginx/sites-available
vim default

在这里插入图片描述
将dist放到nginx的展示目录下。

启动
sudo service nginx start

停止
sudo systemctl stop nginx

重启
sudo service nginx restart

查看状态
sudo service nginx status
ps aux | grep nginx

3、其他

1、安装MySQL

更新
sudo apt update
下载
sudo apt install mysql-server
启动
sudo systemctl start mysql
设置 MySQL 开机自启
sudo systemctl enable mysql
查看状态
sudo systemctl status mysql
登录
mysql -u root -p

2、给MySQL添加新用户

登录
mysql -u root -p

添加新用户,new_user写用户名,password写密码
CREATE USER ‘new_user’@‘localhost’ IDENTIFIED BY ‘password’;

添加权限
GRANT ALL PRIVILEGES ON . TO ‘new_user’@‘localhost’;

刷新权限
FLUSH PRIVILEGES;

退出
EXIT;

3、安装JDK

更新:
sudo apt update

安装 OpenJDK:
sudo apt install openjdk-11-jdk
sudo apt install openjdk-8-jdk

验证安装是否成功:
java -version

设置默认 Java 版本:
sudo update-alternatives --config java

4、使用Nginx向tomcat发token确权,来控制部分资源的访问

nginx的设置:

worker_processes  2;

#工作进程的个数

events {
    worker_connections  1024;
}

http {
	# 支持中文
	charset utf-8;

    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    
    keepalive_timeout  65;

	#可以下多个server 代表开启多个虚拟主机
	server {
        listen       3524;
        # server_name  localhost;	#一般写域名
        # server_name  127.0.0.1;
		default_type text/html;
		# default_type image/jpg;
		
		location / {
			root	html2;		#访问的根目录
			index  index.html;	#默认访问路径(不写的时候访问)
			
			auth_request /validate_token;	#失败返回403  成功进行往下执行
			try_files $uri =401;			
			#$uri代表发来的url地址(这里不能用简写 即/ 而必须是 /index.html)  没有资源返回401
			#try_files 的意思是访问后面的地址
		}
		
		location = /validate_token {
			internal;			#代表只有nginx内部可以访问
			proxy_pass http://127.0.0.1:8088/tokenTest;
		}
	}

    server {
        listen       80;
        # server_name  localhost;
        # server_name  127.0.0.1;
		default_type text/html;

        location / {
            root   html;
            index  index.html;
        }
		
		location /a {
			echo "hello";
		}
		
		location /b {
			echo "bbc";
		}
			
		# 反向代理
		
		location /c {
			proxy_pass https://www.baidu.com/;
		}

		location /e {
			proxy_pass https://www.youtube.com/;
		}
		location /f {
			proxy_pass https://www.bilibili.com/;
		}
		
		# 负载均衡
		location /d {
			proxy_pass http://group1/;
		}
    	# 负载均衡
		upstream group1{
			server 14.215.177.39 weight=1;
			server 127.0.0.1 weight=1;
			# server 9225.35840.9728.2.0.530 weight=1;
			# server 9225:35840:27681:4175:0:255:45055:942 weight=1;
		}
	}
}

token可以放在请求头里:
在这里插入图片描述

springboot获取请求头的写法:

在这里插入图片描述

名词解释:

Spring Boot:

是Spring的进化,约定优于设置(不用搞很多麻烦的配置),嵌入了Tomcat,可以打jar包运行工程

Spring:

Ioc容器:      用注解可以对对象进行管理(创建、注入)
AOP:        面向切面编程
数据访问: 提供了JDBC
事务管理:   在方法层对资源操作的保证(一致性)
MVC:       用在Web开发中 Mould、 View、Control,分层写代码更清晰

SSM:

Spring、Spring MVC 、MyBatis

SSH

Struts(MVC)、Spring、Hibernate(和MyBatis作用类似)

MySQL:

是一个数据库,使用的原因简单理解就是因为它查询数据快,它负责存储数据,而且它是免费的。

MyBatis Plus

是对于MyBatic的优化,就是使用MyBatis Plus的方法不用自己写sql语句(只是对于单表查询的优化)
MyBatis是给Java连接数据库提供的接口,一开始用的是JDBC,
JDBC:作用就是java的抽象层一样,但是可以适配多种数据库,达到代码低耦合的目的。

maven

构建工具,有中央仓库来下载、管理项目依赖(pom来描述项目)

ubuntu

是linux的一个linux的操作系统

linux

是一个操作系统,一般服务器都用linux操作系统。

Vue

JavaScript框架,响应式数据绑定(MVVM)、组件化开发(便于开发、维护)

ElementUI

Vue.js 的前端 UI 框架

SDK

是Software Development Kit 一般指软件开发包,可以包括函数库、编译程序等。

JDK

就是Java Development Kit.简单的说JDK是面向开发人员使用的SDK,它提供了Java的开发环境和运行环境。

JRE

是Java Runtime Enviroment是指Java的运行环境,是面向Java程序的

NDK

Native Development Kit 是用于在 Android 应用中嵌入本地(C/C++)代码的工具集。

VPS

就是服务器,可以放个程序在什么一直跑。
Virtual Private Server,虚拟私有服务器

node.js

JavaScript 运行时环境。它允许开发者使用 JavaScript 编写服务器端应用程序,实现了在浏览器之外运行 JavaScript 的能力。

npm

npm 是 Node.js 包管理器(Node Package Manager)的缩写,是用于管理和分享 JavaScript 代码的工具。它是 Node.js 生态系统的一部分,允许开发者安装、共享、和管理项目中所需的 JavaScript 包(也称为模块)

AJAX

基于 JavaScript 实现,用于发起异步请求

异步请求和同步请求的区别:
同步请求会阻塞程序
异步不会,请求完成后会执行回调函数

Axios

用于发请求的工具(API),基于node.js

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值