前端发起请求,后端响应请求的整个过程
文章目录
- 前端
- 注册页面
- axios 请求方法
- URL 路径配置
- 自定义 axios
- 方法封装
- 后端
- 创建服务器模块
- 接口方法模块
- 连接数据库
本文分为:前端、后端两部分讲诉。以下是前端发送请求到服务器,服务器响应前端,的整个过程的图解:
前端
前端主要是发起请求,本文使用自定义的axios
请求方法,分为注册页面模块、axios 请求方法模块两部分。
前端运行地址: http://localhost:8080/
注册页面
该页面主要是通过点击提交按钮,触发点击事件,发起注册请求。
目标端口是:http://localhost:3000/api/login,协议、域名、端口号之中,存在端口号与前端运行地址不一样,满足跨域请求的条件。后端部分会讲到:如何解决跨域问题。
<el-button type="primary" @click="submitForm('loginForm')">提交</el-button>
点击提交,触发并传递给submitForm
方法参数loginForm
。其中,loginForm
数据形式是
loginForm:{username:"", pass:"",
}
第 7 行,submitForm
发起请求,调用自定义的axios
方法:api.login(){}
import api from "@/api"submitForm(formName) {this.$refs[formName].validate((valid)=> {if(valid){if(this.currentIndex==='login'){api.login(this.loginForm).then(res=>{// 用户登陆成功if(res.data.status === 200){//用户信息存储到 vuex 和 localstoragethis.setUser(res.data)localStorage.setItem('hp',JSON.stringify(res.data))this.$notify({title: '登录成功',type: 'success'});// 用户登陆成功跳转到home页面this.$router.push('/')}else{this.$notify.error({title: '登录失败',message: '请重新登录'});}})}if(this.currentIndex==='register'){api.register(this.registerForm).then(res =>{console.log(res)if(res.data.status === 200){this.$notify({title: '注册成功',type: 'success'});}})}}else{return ;}})
}
axios 请求方法
为了请求方法的应用性更强,选择自定义请求的方式编写封装请求。
考虑到模块开发、代码可读性的好处,将请求方法封装模块分为路径配置、自定义 axios、API封装三部分。
URL 路径配置
每次请求都使用以下预定义的路径,该文件向外导出base
对象
const base = {baseUrl: "http://localhost:3000",register: "/api/register",//用户的接口login: "/api/login",selectTbItemAllByPage: '/api/backend/item/selectTbItemAllByPage',//商品列表请求路径total: "/api/total",//商品总条数search: "/api/search" //商品 模糊查询
}
export default base
自定义 axios
自定义axios
易用、简洁且高效的http
库,对发起的axios
请求和响应进行拦截
// /api/utils/request.js 文件
import axios from "axios
// 引入qs模块,用来序列化post类型的数据
import qs from 'qs'
import router from "@/router"//主要步骤:三步
// 1.创建一个axios实例
// 2.拦截器--请求拦截
// 3.拦截器--响应拦截// 1.创建一个axios实例
const instance = axios.create({timeout: 5000, //超时处理,超过时间告诉用户超时// baseURL: "http://localhost:3000",
})instance.all = axios.all;
instance.spread = axios.spread
// 设置post的请求头
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// interceptors 拦截器
// 2.请求拦截 做一个逻辑后再把请求发送,可以用于配置公用的逻辑,就不用每个请求都配一遍。instance.interceptors.request.use(// 请求拦截配置 // 拦截成功,返回非promise实例对象configconfig => {if (config.method === 'post') {config.data = qs.stringify(config.data);}return config;// 判断token是否存在,存在就添加到请求头上// const token = store.state.loginModule.user.token;// if(token){// config.headers.authorization = store.state.loginModule.user.token;// }},// 拦截失败时,返回promiseerror => Promise.reject(error)
)const toLogin = () => {router.push("/login")
}
// errorHandle打印失败状态码对应的 描述和路由去向
const errorHandle = (status, info) => {switch (status) {case 400:console.log("服务器收到客户端通过PUT或者POST请求提交的表示,表示的格式正确,但服务器不懂它什么意思");toLogin();break;case 401:console.log("客户端试图对一个受保护的资源进行操作,却又没有提供正确的认证证书");toLogin();break;case 403:console.log("客户端请求的结构正确,但是服务器不想处理它");toLogin();break;case 404:console.log("资源被围定义(网络请求地址错误)");break;case 500:console.log("执行请求处理代码时遇到了异常,它们就发送此响应代码");break;case 503:console.log("最可能的原因是资源不足:服务器突然收到太多请求,以至于无法全部处理");break;default:console.log(info);break;}
}
// 3.interceptors拦截器配置response响应拦截
instance.interceptors.response.use(// 成功时response => response.status === 200 ? Promise.resolve(response) : Promise.reject(response),// 失败时error => {const { response } = error;if (response) {errorHandle(response.status, response.data);return Promise.reject(response);} else {console.log("请求被中断");}}
)
// 封装get请求
export function get(url, params) {return new Promise((resolve, reject) => {instance.get(url, params).then(res => {//请求回调成功console.log('封装这里,', params)resolve(res.data);}).catch(err => {reject(err.data);})})
}
// 封装post请求export function post(url, params) {return new Promise((resolve, reject) => {instance.post(url, params).then(res => {//请求回调成功resolve(res.data)}).catch(err => {reject(err.data)})})
}export default instance
方法封装
// api/index.js 文件
// 入口文件
// 导入自定义ajax封装库axios: myaxios
import myaxios from "@/api/utils/request"
// 导入自定义路径配置,模块化开发 简化url
import base from "./base"// 定义前端的发送请求方法
const api = {// 注册请求register(params) {// 调用自定义asiox(myaxios)封装的post方法return myaxios.post(base.baseUrl + base.register, params)}}
}
// 定义的请求方法全部导出
export default api;
后端
本文采用:node.js
+ express
+MySQL
,创建web
服务器,构建后端。后端编写分为服务器模块、接口模块、连接数据库模块三部分,都是server
文件夹下的 js 文件。
后端运行地址:http://127.0.0.1:3000/
创建服务器模块
因此,需要完成获取数据请求必须解决跨域问题,跨域问题可以在前端或者后端解决。本文采取后端解决,使用 CORS
。同源安全策略 默认阻止“跨域”获取资源。但是 CORS
给了 web
服务器这样的权限,即服务器可以选择,允许跨域请求访问到它们的资源。
//接口服务器 server/index.js文件
// 1.导入express
const express = require("express")
//跨域请求处理 后台处理
const cors = require("cors")
//post传参问题
const bodyParser = require("body-parser")
// 导入自定义路由
const router = require("./router")// 2.创建web服务器
const app = express()// 注册中间件
app.use(cors());
// app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }))
//路由访问前缀
app.use('/api', router)// 3.启动服务器
app.listen(3000, () => {console.log('express server running at http://127.0.0.1')
})
其中,web
服务器服务器对象 app
,通过导入接口方法模块,并使用app.use('/api', router)
实现接口方法应用。
接口方法模块
注册的步骤:主要是实现服务器获取请求体的数据,然后将数据插入数据库,最后给客户端响应。
// server/router.js文件
// 设置路由,定义对应post,URL的处理函数
const express = require("express")
// 创建路由对象
const router = express.Router();
//导入数据库配置对象
const sqlClient = require('./dbconfig')
//导入JWT生成token
const JWT = require("jsonwebtoken")
//导入JWT解密
const expressJWT = require("express-jwt")
// 请求post和url=localhost:3000/api/register 的注册路由
const url = require("url");
const { send } = require("process");router.post("/register", (req, res) => {//接收请求对象携带的数据const { username, pass, email } = req.body;//sqlClient实现连接数据库,并将用户数据插入数据库 并回调函数响应数据sqlClient("insert into user values(null,?,?,?)", [username, pass, email], result => {//插入成功 并响应对象数据给客户端if (result.affectedRows > 0) {res.send({status: 200,msg: "注册成功"})} else {res.send({statu: 401,msg: "注册失败"})}})
})
连接数据库
只需要导入mysql
库,即可以实现数据库连接,并向外导出操作数据库的方法对象,该函数返回一个操作结果。
// server/dbconfig.js文件
const mysql = require("mysql")//定义连接对象
const client = mysql.createConnection({host: "localhost",user: "root",password: "root",database: "vue_mall"
})
//定义操作数据库的方法,参数为sql语句,数组数据,回调函数
const sqlClient = (sql, arr, callback) => {client.query(sql, arr, (error, result) => {if (error) {//发生错误,返回错误信息console.log(error)return}//成功,则调用回调函数返回操作的结果callback(result)})
}
module.exports = sqlClient
使用 mysql
对象的createConnection
方法创建连接数据库对象 client
,然后 定义一个sqlClient
对象,其中 sqlClient
需要参数sql语句,数组数据,便会调用回调函数,并返回sql语句和数据操作数据库的结果。
前端发起请求,后端响应请求的整个过程相关推荐
- ajax 直接向后台发送请求,通过ajax异步向后端发送请求,响应请求向前端传送json格式数据的实现思路...
一.前端异步请求代码: $.ajax ({ type: "POST",//请求的方式 url: "outputservlet3",//请求url data: { ...
- web-http协议-请求协议-响应协议
http概述 = 理解,什么是无状态的协议 通过抓包的方式,关注,请求的发生 = 重点,关注这样的词 请求,响应 请求协议 >看请求头 查看网络请求,详细了解内容 accept,接受 浏览器,告 ...
- 【JavaLearn】#(23)JSP相关语法、HTTP协议、Servlet介绍、Servlet生命周期、请求和响应、相对路径、转发和重定向
1. JSP简单内容 1.1 JavaEE JavaEE 包含JSP JavaEE是一个开发分布式企业级应用的规范和标准.JavaEE包含之前学过的所有内容(JavaSE) 真正开发中,很少使用Jav ...
- SpringMVC学习----请求与响应
请求与响应 请求映射路径 提出问题 解决方法 细分请求路径 UserController类 BookController类 在类上方配置的请求映射 请求 请求方式 请求方法 GET请求 传入参数结果 ...
- 前端性能优化学习 05 请求和响应优化 01(DNS 解析、HTTP 长连接、HTTP2、避免重定向、压缩传输的数据资源)
请求和响应优化 目的:更快的内容到达时间. 核心思路: 更好的连接传输效率 更少的请求数量 更小的资源大小 合适的缓存策略 最佳实践: 减少 DNS 查找:每次主机名的解析都需要一次网络往返,从而增加 ...
- Vue项目中前端请求后端数据的两种方式
1.JS方式,使用fetch函数,较底层 //JS方式请求分页数据 fetch("http://localhost:9090/user/page?pageNum=" +this.p ...
- 应用服务器与WSGI协议以及flask后端框架总结(后端接收请求返回响应的整个流程)...
上次遗留了两个问题,先说一下自己的看法 问题: 1.明明一个线程只能处理一个请求,那么栈里的元素永远是在栈顶,那为什么需要用栈这个结构?用普通变量不行吗. 2._request_ctx_stack和_ ...
- Java 技术篇 - 前端浏览器发送一次url请求后端ServerSocket接收到两次请求原因及解决方法,GET /favicon.ico HTTP/1.1问题处理
效果图如下: 前端发送一次请求,后端接收到两次,第二次是:GET /favicon.ico HTTP/1.1 可以看到页签上标题栏前面是个地球,这个是默认的. 原因就是后台给的响应里没有指定这个图标, ...
- 前端请求后端数据的三种方式!
在前后端分离的开发项目中,前后端联调的时候会出现这样那样的问题,尤其是在调取数据的程序上面,有时候前端给的前端给到后端的明明是正确的但就是无法拿到正确的数据,下面小千就来给大家详解一下常见的三种数据传 ...
最新文章
- 强行分类提取特征自编码网络例3
- HDU4472 Count
- mac电脑如何与手机同步复制粘贴_苹果换安卓手机如何同步手机自带备忘录便签?...
- 满足 Google Play 目标 API 等级 (targetSdkLevel) 的要求
- 高德软件测试工资,【高德工资】软件测试工程师待遇-看准网
- 前端开发学习笔记(一)深入浅出Javascript
- adb 重命名_adb中常用的命令
- Data intensive Application (1)
- C#LeetCode刷题-树
- C# textBox框实现输入像百度搜索出现下拉列表的格式
- windows清除记住的密码
- java地址值是几进制_Java三种进制的数值常量操作代码
- 基于java(springboot框架)的新闻管理系统 开题报告
- TLQ 异常杀进程清理 IPC 操作步骤
- java出现圅_java获取汉字拼音首字母A
- Windows 10 Build 16226发布:任务管理器新增GPU追踪
- Latex文献报错 Something‘s wrong--perhaps a missing \item. \end{thebibliography}
- python分割文件_python简单分割文件的方法
- 【100%通过率】华为OD机试真题 Python 实现【获取最大软件版本号】【2022.11 Q4 新题】
- Word高效指南 - 快速合并多个文档