浪花 - 搜索标签前后端联调

前传:浪花 - 根据标签搜索用户-CSDN博客

目录

一、完善后端搜索标签接口

二、前后端搜索标签接口的对接

1. 使用 Axios 发送请求

2. 解决跨域问题

3. Axios 请求传参序列化

4. 接收后端响应数据

5. 处理后端响应数据格式

6. 搜索结果为空的页面展示 

附:解决跨域问题的几种方式

1. 方式一:修改域名和端口

2. 方式二:网关支持(Nginx)——添加允许跨域配置

3. 方式三:后端服务支持


一、完善后端搜索标签接口

1. 添加 Controller 层:调用 userService 中之前写好的 searchUsersByTags() 来根据前端传来的标签搜索过滤数据库中的用户

    /**
     * 根据标签搜索用户
     * @param tagNameList 标签列表
     * @return 搜索到的用户列表
     */
    @GetMapping("/search/tags")
    public BaseResponse<List<User>> searchUsersByTags(@RequestParam(required = false) List<String> tagNameList) {
        if(CollectionUtils.isEmpty(tagNameList)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        List<User> userList = userService.searchUsersByTags(tagNameList);
        return ResultUtils.success(userList);
    }

2. 启动项目,测试接口

  • 使用 Knife4j 接口文档传递参数进行接口调试
  • 传递空的标签列表:后端做了请求参数是否为空的校验,参数为空抛出异常,全局异常处理器会进行统一处理

  • 传递正确参数:后端根据参数列表(标签)过滤出来的用户列表数据

数据库暂时只有一个用户有标签信息,所以响应数据的用户列表只有一个用户

二、前后端搜索标签接口的对接

参考官方文档:axios中文网|axios API 中文文档 | axios (axios-js.com)

1. 使用 Axios 发送请求

  • 整合 Axios

    npm install axios
  • 创建 Axios 实例并定义 baseURL:baseURL 作为请求的前缀,后续修改主机和端口号(项目部署上线时)只需要修改 baseURL 即可,不需要修改所有请求地址的前缀
const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});
  • 定义全局请求拦截器和全局响应拦截器
// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Do something with response data
    return response;
  }, function (error) {
    // Do something with response error
    return Promise.reject(error);
  });
  •  发送搜索请求:点击搜索按钮进入搜索结果页面时,页面一加载就发送 GET 请求
axios.get('/user?ID=12345')
  .then(function (response) {
    // handle success
    console.log(response);
  })
  .catch(function (error) {
    // handle error
    console.log(error);
  })
  .then(function () {
    // always executed
  });
  • 引起跨域问题
Access to XMLHttpRequest at 'http://localhost:8080/api/user/search/tags' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

 

2. 解决跨域问题

  • 这里使用后端支持的方式解决跨域问题
  • 在 Controller 前添加注解 @CrossOrigin:默认允许所有地址跨域,也可以指定特定地址

 @CrossOrigin(poigins = { "http://user.zhulang-user-center.top" }, methods = { RequestMethod.POST })
  • 跨域访问成功✔

  •  参数传递出现问题:传递格式有误,tagNameList 多了 [],传到后端无法识别

3. Axios 请求传参序列化

  • 安装 qs 库:querystring parser 参数字符串解析器
  • 再次发送请求
import {onMounted, ref} from "vue";
import myAxios from "/src/plugins/myAxios.js";
import qs from 'qs';

const { tags } = route.query;

onMounted( () => {
  myAxios.get('/user/search/tags', {
    params: {
      tagNameList: tags,
    },
    paramsSerializer: params => {
      return qs.stringify(params, {indices: false})
    }
  })
  .then(function (response) {
    // handle success
    console.log("/user/search/tags succeed", response);
  })
  .catch(function (error) {
    // handle error
    console.log("/user/search/tags error", error);
  })
  .then(function () {
    // always executed
  });
})
  • 请求参数格式正常
http://localhost:8080/api/user/search/tags?tagNameList=%E7%94%B7
  • 查看后端是否接收到请求参数:接收成功并响应给前端

4. 接收后端响应数据

  • 修改之前的模拟数据(之前的搜索结果页面只放了一个 mockUser 进行测试)
  • 接受 GET 请求发送后,后端返回的用户列表存入 userList,在 Card 商品卡片组件中遍历展示
  • await 关键字:等 myAxios 请求从后端获取到数据再存到 userListData 中
  • 请求成功 .then() 响应函数:返回响应数据,从 response 对象中获取 response.data?.data
<script setup lang="ts">

import { useRoute } from'vue-router'
import {onMounted, ref} from "vue";
import myAxios from "/src/plugins/myAxios.js";
import qs from 'qs';
import type {UserType} from "@/models/user";


const route = useRoute();
const { tags } = route.query;
const userList = ref([]);

onMounted( async () => {
  const userListData: UserType[] = await myAxios.get('/user/search/tags', {
    params: {
      tagNameList: tags,
    },
    paramsSerializer: params => {
      return qs.stringify(params, {indices: false})
    }
  })
    .then(function (response) {
      // handle success
      console.log("/user/search/tags succeed", response);
      return response.data?.data;
    })
    .catch(function (error) {
      console.log("/user/search/tags error", error);
    })
  if(userListData) {
    userList.value = userListData;// userListData 存在则赋给 userList 进行展示
  }
})

</script>

5. 处理后端响应数据格式

问题:后端保存的标签 tags 是 JSON 字符串格式,前端把每个字符都解析成了一个数组元素,即每个字符都被解析成了一个标签

  • 在前端解析后端响应的 JSON 格式的字符串:将 JSON 转为数组
  if(userListData) {
    userListData.forEach(user => {
      if(user.tags) {
        user.tags = JSON.parse(user.tags);
      }
    });
    userList.value = userListData;
  }
  • 查看效果

6. 搜索结果为空的页面展示 

  • 引入 Vant 提供的 Empty 组件

参考官方文档:Empty 空状态 - Vant 3 (gitee.io)

  <van-empty image="search" description="暂无符合要求的用户" />
  • 查看页面效果

附:解决跨域问题的几种方式

什么是跨域?

  • 浏览器的安全问题,仅允许向同协议、同域名、同端口的服务器发送请求
  • 前后端交互时有一个不同都会引起跨域

1. 方式一:修改域名和端口

  • 将前后端服务的端口修改成一样的,比如都是 localhost:8080
  • 通过访问路径(前缀)来转发到不同端口,比如访问 /api 就转发到 8080 端口

2. 方式二:网关支持(Nginx)——添加允许跨域配置

  • proxy_pass:在配置文件中添加反向代理
  • $http_origin:是 Nginx 的内置变量,设置允许所有域名跨域,但是和 * 号有点不同,* 不能和下一句的 Access-Control-Allow-Credentials 一起使用
  • Access-Control-Allow-Credentials 设为 true,表示允许前端带上 cookie 请求
  • 如果请求是预检请求 OPTIONS,直接返回成功 204
# 跨域配置
location ^~ /api/ {
    proxy_pass http://127.0.0.1:8080/api/;
    add_header 'Access-Control-Allow-Origin' $http_origin;
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers '*';
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Origin' $http_origin;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    }
}

3. 方式三:后端服务支持

  • SpringBoot 项目直接在接口首部加上注解 @CrossOrigin 表示允许跨域即可

  • 后端支持跨域的好处

    • 灵活管理多个前端的不同跨域限制:如允许域名 A 的 GET 请求跨域,域名 B 的POST 请求跨域

    • 后端统一管理更加安全

    • 前端不用反复写跨域配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/327967.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HCIA——11计算机网络分层结构——OSI/ISO、TCP/IP

学习目标&#xff1a; 参考模型 计算机网络 1.掌握计算机网络的基本概念、基本原理和基本方法。 2.掌握计算机网络的体系结构和典型网络协议&#xff0c;了解典型网络设备的组成和特点&#xff0c;理解典型网络设备的工作原理。 3.能够运用计算机网络的基本概念、基本原理和基本…

Pycharm 神级插件 Grep Console

下载: 使用: 为了方便测试这款插件的功能,我们可以写一段代码 来测试 import logging import time# 配置日志 logging.basicConfig(levellogging.DEBUG) logger logging.getLogger(__name__)# 日志消息中的字典内容 log_message """ {413867144: {202401031…

计算机导论09-数据组织与管理

文章目录 数据管理基础数据管理技术的发展数据组织与管理的发展手工数据处理阶段文件方式的数据处理阶段数据库数据处理阶段 数据库技术的发展 数据模型数据模型的要素概念模型逻辑模型 数据库系统数据库系统基础数据库系统构成 数据库系统的结构数据库系统的体系结构数据库系统…

smartgit选择30天试用后需要输入可执行文件

突然有一天smartgit提示到期了&#xff0c;我按照以往那样删除license和preferences文件后&#xff0c;选择30天试用&#xff0c;弹出了需要选择git可执行文件。 我尝试选择了我的git.exe&#xff0c;发现根本不行&#xff0c;提示让我执行下git --version 执行过后提示我的.gi…

HCIP之ISIS实验

华子目录 实验拓扑及要求规划IP地址规划Level1/2路由器实验步骤配置IP地址启动ISIS修改对应路由类型路由泄露&#xff1a;R1访问R5走R6测试 实验拓扑及要求 规划IP地址 规划Level1/2路由器 实验步骤 配置IP地址 R1-R8依次类推 [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip a…

【Java SE】类和对象详解

文章目录 1.什么是面向对象2. 类的定义和使用2.1 简单认识类2.2 类的定义格式 3. 类的实例化3.1 什么是实例化3.1.1 练习&#xff08;定义一学生类&#xff09; 3.2 类和对象的说明 4. this 引用5. 构造方法6. 对象的初始化6.1 默认初始化6.2 就地初始化 7. 封装7.1 封装的概念…

WhatsApp Business有哪些好处?

WhatsApp 被认为是全球领先的移动通讯应用程序&#xff0c;在全球拥有约20 亿月活跃用户&#xff0c;已成功跻身全球最受欢迎的社交平台Top3。由于其显著增长的知名度和WhatsApp Business的加入&#xff0c;WhatsApp 已成为企业与其客户互动沟通最有效的方式之一。 使用WhatsA…

MySQL面试题 | 12.精选MySQL面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Vue-23、Vue过滤器

1、效果 2、过滤器实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>过滤器</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm/vue2/dist/vue.…

如何在云端加速缓存构建

缓存是指将某类数据存储起来以便以后重复使用的过程&#xff0c;它的运用在开发场景中非常普遍。类似于你习惯把最常用的调料放在厨房台面上&#xff0c;而不是橱柜里&#xff0c;这样你在准备大餐时就可以轻松取用。 但对于一个更为技术性、更精确的用例&#xff0c;比如像谷…

linux单机部署mysql(解压编译方式)

一、下载官网压缩包&#xff08;tar.gz&#xff09; MySQL :: Download MySQL Community Serverhttps://dev.mysql.com/downloads/mysql/根据自己的操作系统发行版本、位数、gclib版本、mysql版本来选择对应的压缩包 比如我是 linux系统debian10&#xff08;官网只有linux ge…

【文本到上下文 #3】:文本表示技术

一、说明 欢迎回到“完整的 NLP 指南&#xff1a;文本到上下文” 在上一篇文章中&#xff0c;我们对自然语言处理 (NLP) 中的基本数据预处理步骤进行了令人着迷的探索。我们剖析了标记化、文本清理、停用词删除、词干提取和词形还原、词性标记和命名实体识别 (NER) 的复杂性。这…

自动驾驶轨迹规划之碰撞检测(二)

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 目录 1.基于凸优化 2.具身足迹 3. ESDF 自动驾驶轨迹规划之碰撞检测&#xff08;一&#xff09;-CSDN博客 大家可以先阅读之前的博客 1.基于…

探索数据的奥秘:一份深入浅出的数据分析入门指南

数据分析 书籍推荐 入门读物 深入浅出数据分析啤酒与尿布数据之美数学之美 数据分析 Scipy and NumpyPython for Data AnalysisBad Data Handbook集体智慧编程Machine Learning in Action机器学习实战Building Machine Learning Systems with Python数据挖掘导论Machine L…

循环神经网络-单变量序列预测详解(pytorch)

参考博客 文章目录 &#xff08;1&#xff09;导入所需要的包&#xff08;2&#xff09;读取数据并展示&#xff08;3&#xff09;数据预处理&#xff08;4&#xff09;划分训练集和测试集&#xff08;5&#xff09;构建RNN回归模型&#xff08;6&#xff09;构造训练函数&…

Vue3响应式系统(三)

Vue3响应式系统(二)https://blog.csdn.net/qq_55806761/article/details/135612738 七、无限递归循环。 响应式系统里无限递归也是需要考虑到的。 什么情况会出现无限递归循环&#xff1f; 代码示例&#xff1a; const data { foo: 1 } const obj new Proxy(/* * */) effe…

金融CRM系统是什么?有哪些功能和作用

今年市场经济下行&#xff0c;投资趋向于保守、人们消费降级&#xff0c;对于金融行业来说影响很大。受经济形式的影响加上行业的数字化转型升级&#xff0c;金融企业都在寻求客户管理的新策略&#xff0c;维护好忠实客户、吸引新客户投资。小编认为CRM系统是管理客户的不二之选…

LLM之RAG实战(十六)| 使用Llama-2、PgVector和LlamaIndex构建LLM Rag Pipeline

近年来&#xff0c;大型语言模型&#xff08;LLM&#xff09;取得了显著的进步&#xff0c;然而大模型缺点之一是幻觉问题&#xff0c;即“一本正经的胡说八道”。其中RAG&#xff08;Retrieval Augmented Generation&#xff0c;检索增强生成&#xff09;是解决幻觉比较有效的…

ROS第 6 课 编写简单的订阅器 Subscriber

文章目录 第 6 课 编写简单的订阅器 Subscriber1. 编写订阅者节点2. 测试发布者和订阅者 第 6 课 编写简单的订阅器 Subscriber 订阅器是基于编辑了发布器的基础上创建的&#xff0c;只有发布了消息&#xff0c;才有可能订阅。若未编辑发布器&#xff0c;可前往"ROS第5课 …

C语言练习day7

数包含9的数 包含数字9的数_牛客题霸_牛客网 题目&#xff1a; 思路&#xff1a;首先&#xff0c;我们得生成1~2019之间的数字&#xff0c;其次再通过各个位数来比较是否等于9&#xff0c;若等于&#xff0c;则记录一次&#xff0c;反之&#xff0c;不记录。 代码演示&…
最新文章