飞道的博客

nodejs+vue+element+eachers构建开源项目大型连续剧(5)前端请求封装,完成用户注册。

630人阅读  评论(0)

        在前端项目开发中,一个好的请求封装可以给我们带来诸多便利,减少了代码重复,优化了问题处理等。那接下来我们一起学习一下怎么做到对一个请求的简单封装吧。主要通过对axios请求的二次封装,实现页面的请求以及必要的优化。

一、引入axios

        学习第一步,安装加引入。(押韵,哈哈哈)

        安装axios

npm install axios

        新建utils文件夹下request.js文件用于请求的封装,初始化的封装,后面我们一步步来。


  
  1. import axios from axios
  2. const service=axios. create({
  3. baseURL: '', //请求地址
  4. timeout: 1000, //请求超时时间,如果超给改时间会中断
  5. // headers: {'X-Custom-Header': 'foobar'}//自定义请求头
  6. })
  7. //添加请求拦截器
  8. service. interceptors. request. use( (config)=> {
  9. // 在发送请求之前做些什么
  10. return config;
  11. }, (error)=> {
  12. // 对请求错误做些什么
  13. return Promise. reject(error);
  14. });
  15. //添加响应拦截器
  16. service. interceptors. response. use( (response)=> {
  17. // 对响应数据做点什么
  18. return response;
  19. }, (error)=> {
  20. // 对响应错误做点什么
  21. return Promise. reject(error);
  22. });
  23. export default service

        大家会发现url是空的,在开发中这个url一般都是动态的,更加环境去切换的这个地方需要插播一个小知识关于.env文件的使用。

二、关于.env文件的使用

        1.模式

                在vue-cli中模式是一个重要的概念,默认情况下有三个模式。

                对于下面所说的命令,大家可以看一下项目中的package.json文件,一看就明白了

  1. development 模式用于 vue-cli-service serve
  2. production 模式用于 vue-cli-service build 和 vue-cli-service test:unit
  3. test 模式用于 vue-cli-service test:unit

development模式对应我们开发环境对应的命令是 serve命令,也就是说我们启动项目后就在development模式下运行

production模式对应打包命令build。打包后在production模式下运行

你可以通过传递 --mode 选项参数为命令行覆写默认的模式。例如,如果你想要在构建命令中使用开发环境变量:

vue-cli-service build --mode development

                总结,可以通过命令动态配置,配置对于模式下对应那些配置。

                我们一般通过.env文件进行请求地址的配置,例如存在多个地址的情况,可以通过命令进行灵活配置。

        2.process.env环境对象

                process.env 是 Node.js 中的一个环境对象。其中保存着系统的环境的变量信息。可使用 Node.js 命令行工具直接进行查看(如下图所示)。

                在不同的模式会有不同的环境变量

在 development 模式下 NODE_ENV 的值会被设置为 “development”
在 production模式下 NODE_ENV 的值会被设置为 “production” 

        3..env文件的执行顺序

.env 无论开发环境还是生产环境都会加载的配置文件
.env.development 开发环境加载的配置文件
.env.production 生产环境加载的配置文件

研发环境 加载顺序:.env .env.development 同一个变量名 后者会覆盖前者
生产环境 加载顺序:.env .env.production 同一个变量名 后者会覆盖前者

三、配置开发环境下的请求地址

        因为我们现在是在开发模式,所以在.env.development文件中配置我们需要请求的地址(如下)。

        对应的ip需要填写服务器ip和对应端口号

# just a flag
NODE_ENV = 'development'

# base api
 VUE_APP_BASE_API = 'http://10.0.0.165:9588'

        然后我们上面的请求url就可以拿到对应的值了


  
  1. const service=axios. create({
  2. baseURL: process. env. VUE_APP_BASE_API, //请求地址
  3. timeout: 10000, //请求超时时间,如果超给改时间会中断
  4. // headers: {'X-Custom-Header': 'foobar'}//自定义请求头
  5. })

        然后我们建立api文件夹进行接口的模块化区分,不同模块对应不同的模块js。

         进行一个get请求进行封装是否成功的测试


  
  1. import request from "@/utils/request";
  2. export function list( ){
  3. return request({
  4. url: `/api/list`,
  5. method: "get"
  6. })
  7. }

         这是第一集用于测试服务器开发get请求的接口,当时我们测试是成功的。因为测试,所以我们怎么简单怎么来,主要是测试是否成功。

        在app.vue页面,进行一个简单的请求


  
  1. <template>
  2. <div id="app">
  3. <router-view/>
  4. </div>
  5. </template>
  6. <script>
  7. import {list} from '@/api/list'
  8. export default {
  9. created( ){
  10. list(). then( res=>{
  11. console. log(res);
  12. })
  13. }
  14. }
  15. </script>
  16. <style lang="less">
  17. @import "@/assets/style/reset.css";
  18. </style>

        然后重点来了!!!哈哈哈哈,报错了,告诉我跨域了,然后就大结局了,再见了各位。

           

        然而并没有结束,让我们一起解决跨域吧,

        前端:后台,跨域了,你解决下

        后端:自己解决,前端配置代理不会么?

        前端:离职,不干了

        现在,我们是后端了,作为一个前端喜欢的后端,我只能说,我来搞,交给我!!!(虽然前后端都是我,呜呜呜)

四、后端通过cors解决跨域

        其实对于后端来说,解决跨域很简单,只需要使用CORS就可以了,一共需要两步

        第一步:安装cors

yarn add cors

npm install cors

npm和yarn都可以哈,yarn安装快一点,各凭喜好

        第二步:使用cors()解决跨域

        以下是nodejs服务器端的代码,app.js文件中引入并使用

//引入

const cors = require('cors')

//使用

app.use(cors())

        然后再继续请求试一下,发现跨域就这样解决了。

 五、关于跨域的相关知识

    cors又称跨域资源共享,由一系类HTTP响应头组成,这些HTTP响应头决定浏览器是否组织前端JS代码跨域获取资源,实际情况是,前端同意请求,服务器同意响应,浏览器不同意这门亲事

    浏览器的同源安全策略(端口、域名、协议有一个不同就不能通信)默认会阻止网页“跨域”获取资源,但如果接口服务器配置了CORS相关的响应头就可以解除浏览器端的跨域访问限制。就好像服务器拿着彩礼来了,浏览器就同意的这门亲事。

     CORS主要在服务器端配置,客户端无需做任何处理。cors有兼容性(2022年可忽略不不计,主要是低版本服务器的兼容性)。

      

六、前端页面开发

页面展示:

 

代码:

页面:


  
  1. <template>
  2. <div class="login">
  3. <div id="login_box">
  4. <el-form
  5. :model= "ruleForm"
  6. :rules= "rules"
  7. ref= "ruleForm"
  8. label-width= "100px"
  9. class= "demo-ruleForm"
  10. >
  11. <el-form-item label="用户名" prop="username">
  12. <el-input v-model="ruleForm.username"> </el-input>
  13. </el-form-item>
  14. <el-form-item label="密码" prop="password">
  15. <el-input
  16. v-model= "ruleForm.password"
  17. type= "password"
  18. show-password
  19. > </el-input>
  20. </el-form-item>
  21. <el-form-item label="确认密码" prop="verification" v-if="!loginstate">
  22. <el-input
  23. v-model= "ruleForm.verification"
  24. type= "password"
  25. show-password
  26. > </el-input>
  27. </el-form-item>
  28. <el-form-item>
  29. <el-button type="primary" v-if="loginstate" @click="login"
  30. >登录</el-button
  31. >
  32. <el-button type="primary" v-else @click="login">注册 </el-button>
  33. <el-button @click="loginstate = !loginstate">切换{{ loginstate?'注册':'登录' }} </el-button>
  34. </el-form-item>
  35. </el-form>
  36. </div>
  37. </div>
  38. </template>
  39. <script>
  40. import { reguser } from "@/api/login";
  41. export default {
  42. data( ) {
  43. var validatePass = ( rule, value, callback) => {
  44. if (value === "") {
  45. callback( new Error( "请输入密码"));
  46. } else {
  47. if ( this. ruleForm. verification !== "") {
  48. this. $refs. ruleForm. validateField( "verification");
  49. }
  50. callback();
  51. }
  52. };
  53. var validatePass2 = ( rule, value, callback) => {
  54. if (value === "") {
  55. callback( new Error( "请再次输入密码"));
  56. } else if (value !== this. ruleForm. password) {
  57. callback( new Error( "两次输入密码不一致!"));
  58. } else {
  59. callback();
  60. }
  61. };
  62. return {
  63. //当前的状态,true为登录
  64. loginstate: true,
  65. ruleForm: {
  66. username: "",
  67. password: "",
  68. verification: "",
  69. },
  70. rules: {
  71. username: [
  72. { required: true, message: "请输入用户名", trigger: "blur" },
  73. ],
  74. password: [
  75. { required: true, validator: validatePass, trigger: "blur" },
  76. ],
  77. verification: [
  78. { required: true, validator: validatePass2, trigger: "blur" },
  79. ],
  80. },
  81. };
  82. },
  83. methods: {
  84. login( ) {
  85. //用来判断是登录还是注册
  86. const { loginstate } = this;
  87. const { username, password } = this. ruleForm;
  88. this. $refs. ruleForm. validate( (valid) => {
  89. if (valid) {
  90. //验证成功
  91. if (loginstate) {
  92. //登录
  93. } else {
  94. //注册
  95. const data = {
  96. username,
  97. password,
  98. };
  99. reguser(data). then( (res) => {
  100. const {code,data}=res. data
  101. if(code=== 200){
  102. this. loginstate= true
  103. this. $message. success( '用户注册成功,请登录。');
  104. } else{
  105. this. $message. error(data);
  106. }
  107. });
  108. }
  109. }
  110. });
  111. },
  112. },
  113. };
  114. </script>
  115. <style lang="less" scoped>
  116. .login {
  117. background: url( "https://cdn.pixabay.com/photo/2018/08/14/13/23/ocean-3605547_1280.jpg")
  118. no-repeat;
  119. background-size: 100% 100%;
  120. width: 100vw;
  121. height: 100vh;
  122. overflow: hidden;
  123. }
  124. #login_box {
  125. width: 20vw;
  126. background-color: #00000060;
  127. margin: auto;
  128. margin-top: 15%;
  129. text-align: center;
  130. border-radius: 10px;
  131. padding: 50px 50px;
  132. }
  133. </style>

 

后面发现请求后后台获取不到我们传递的body参数,因为axios默认传递的post参数格式是application/json,所以我们需要进行一定的配置,

通过body-parser解决上述问题,代码:(记得先安装)


  
  1. //导入express
  2. const express = require( 'express')
  3. //引入cors解决跨域问题
  4. const cors = require( 'cors')
  5. //用于解决fromdata格式数据获取不到的问题
  6. const bodyParser = require( 'body-parser');
  7. //创建web服务器
  8. const app = express()
  9. //解决跨域
  10. app. use( cors())
  11. //数据JSON类型
  12. app. use(bodyParser. json());
  13. //解析post请求数据
  14. app. use(bodyParser. urlencoded({ extended: false }));
  15. //将文件部署到服务器
  16. app. use(express. static( 'img'))
  17. //配置解析表单数据(application/x-www-form-urlencoded)格式的中间件
  18. app. use(express. urlencoded({ extended: false }))
  19. const userRouter = require( "./router/user")
  20. app. use( '/api', userRouter)
  21. // 通过ap.listen进行服务器的配置,并启动服务器,接收两个配置参数,一个是对应的端口号,一个是启动成功的回调函数
  22. app. listen( 9588, () => {
  23. console. log( '服务器启动成功');
  24. })


转载:https://blog.csdn.net/ct5211314/article/details/128315082
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场