基于SpringBoot + Vue点赞功能的实现

一、功能分析

        该功能是在个人博客项目开发的过程中遇到的一个技术难点,该博客项目是一个基于springboot的前后端分离的项目,因此在点赞评论时,获取用户id是一个技术难点,下面就来分享一下小一在开发该功能的一些经验。

二、解决前后端分离项目的跨域问题

        1、首先,我们要了解什么是跨域问题。跨域是指跨域名:域名,记忆网络电脑ip很难记,就给它取了一个名字来记忆,这个名字就要域名。域名最终要被转换为ip地址,例如:

www.baidu.com   220.181.38.148

www.jd.com         211.144.24.218

跨域是指跨域名的访问,从一个域名的系统去访问另一个域名系统,以下情况都属于跨域:

ip地址和端口号只要有一个不一样都是跨域

        2、跨域不一定会有跨域问题,因为跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。因此,跨域问题是针对ajax的一种限制,同步请求是不存在跨域问题的。

        3、跨域问题的解决方案      

跨域解决方案有很多,链接:9种常见的前端跨域解决方案(详解)_慕课手记 。本项目选用如下方案

  • 后端CORS跨域

    @Configuration
    public class GlobalCorsConfig {
        @Bean
        public CorsFilter corsFilter() {
            //1.添加CORS配置信息
            CorsConfiguration config = new CorsConfiguration();
            //1) 允许的域,不要写/,否则cookie就无法使用了
            //允许后台系统的前端项目访问接口
            config.addAllowedOrigin("http://127.0.0.1:8081");
            config.addAllowedOrigin("http://localhost:8081");
            //允许前台系统的前端项目访问接口
            config.addAllowedOrigin("http://127.0.0.1:80");
            config.addAllowedOrigin("http://localhost:80");
            config.addAllowedOrigin("http://127.0.0.1");
            config.addAllowedOrigin("http://localhost");
    //        config.addAllowedOrigin("*");
    
            //2) 是否允许发送Cookie信息
            config.setAllowCredentials(true);
            //3) 允许的请求方式
            config.addAllowedMethod("OPTIONS");
            config.addAllowedMethod("HEAD");
            config.addAllowedMethod("GET");
            config.addAllowedMethod("PUT");
            config.addAllowedMethod("POST");
            config.addAllowedMethod("DELETE");
            config.addAllowedMethod("PATCH");
            // 4)允许的头信息
            config.addAllowedHeader("*");
            
            //2.添加映射路径,我们拦截一切请求
            UrlBasedCorsConfigurationSource configSource = new
                    UrlBasedCorsConfigurationSource();
            configSource.registerCorsConfiguration("/**", config);
            //3.返回新的CorsFilter.
            return new CorsFilter(configSource);
        }
    }

其实在前端也可解决跨域问题,只需要在前端Vue脚手架项目的main.js中配置相关信息即可:

axios.defaults.withCredentials = true;  //当前请求为跨域类型时,是否在请求中协带cookie

三、点赞功能分析与实现

        1、点赞功能分析

点赞功能是在我们日常浏览网站,app,微信朋友圈,qq等应用中最常见的功能之一,该项目的开发也设计了该功能。

        1)首先点赞功能呈现在用户视野里的是一个按钮图标,点击会更改图标颜色,所以就有一个初始化状态为未点赞状态

        2)用户是否点过赞的判断,目的是为了防止恶意的刷赞,同一个用户id只能点赞一次,可以点赞也可以取消点赞。

        3)用户点赞或取消点赞过后,图标状态的回显。

        2、点赞功能的实现

Vue页面发送请求:
//10.点击点赞实现逻辑
            handleStar(){
                this.$http.put("/blogArticle/updateStar/" + this.id).then(res=>{
                    if (res.data.success){
                        if (res.data.message == "cancel"){
                            //设置点赞图标的颜色 - 未点赞
                            this.starIcon = "bi bi-hand-thumbs-up opacity-50";
                        }else {
                            //设置点赞图标的颜色 - 已点赞    
                            this.starIcon = "bi bi-hand-thumbs-up-fill opacity-50"
                        }
                        //调用查询文章详情方法
                        this.getArticleByID();
                    }else {
                        this.$message.error("系统繁忙,请稍后重试【500】");
                    }
                }).catch(res=>{
                    this.$message.error("系统繁忙,请稍后重试【400,404】");
                })
            },
 //11.页面加载点赞图片样式
            getInitIconClass(){
                let url = location.href;
                let articleId = url.substring(url.lastIndexOf("?") + 1)//获取文章id
                this.$http.get("blogArticle/initIconClass/" + articleId).then(res=>{
                    if (res.data.message == "ok"){ //已经点赞过的
                        this.starIcon = "bi bi-hand-thumbs-up-fill opacity-50";
                    }else{//这个电脑还没有点赞
                        this.starIcon = "bi bi-hand-thumbs-up opacity-50";
                    }
                }).catch(res=>{
                    this.$message.error("系统繁忙,请稍后重试【400,404】")
                })
            }
后台代码controller接口:
/**
     * 前台系统点赞功能接口
     * @param id
     * @param request
     * @return
     */
    @PutMapping("/updateStar/{id}")
    @ApiOperation(value = "前台系统 - 点赞功能")
    public AjaxResult updateStar(@PathVariable("id") Long id, HttpServletRequest request){
        try {
            return blogArticleService.updateStar(id,request);
        } catch (Exception e) {
            e.printStackTrace();//打印错误信息
            return new AjaxResult(false,"网络异常,请稍后再试!!!");
        }
    }

    /**
     * 业务接口:前台点赞图片样式加载
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/initIconClass/{id}")
    @ApiOperation(value = "前台系统 - 页面加载点赞图片样式")
    public AjaxResult initIconClass(@PathVariable("id")Long id,HttpServletRequest request){
        try {
            return blogArticleService.initIconClass(id,request);
        } catch (Exception e) {
            e.printStackTrace();
            return new AjaxResult(false,"网络异常,请稍后再试!!!");
        }
    }
后台代码service实现类:
 @Override
    public AjaxResult updateStar(Long id, HttpServletRequest request) {
        //通过文章id查询ip地址
        List<String> address = ipAddressMapper.findByArticleId(id);
        //获取请求中的地址
        String ip = request.getRemoteAddr();
        if (address.contains(ip)){//数据库有ip地址 - 以前点赞了 - 再点就是取消点赞
            ipAddressMapper.delByIpAndArticleId(ip,id);
            blogArticleMapper.decreStar(id);
            return AjaxResult.me().setMessage("cancel");
        }else {
            IpAddress ipAddress = new IpAddress();
            ipAddress.setAddress(ip);
            ipAddress.setArticleId(id);
            ipAddressMapper.add(ipAddress);
            blogArticleMapper.increStar(id);
            return AjaxResult.me().setMessage("star");
        }
    }

    @Override
    public AjaxResult initIconClass(Long id, HttpServletRequest request) {
        List<String> ips = ipAddressMapper.findByArticleId(id);
        String ip = request.getRemoteAddr();
        if (ips.contains(ip)){//数据库有mac地址 - 以前点赞过 - 再点就是取消点赞
            return AjaxResult.me().setMessage("ok");
        }else {
            return AjaxResult.me().setMessage("no");
        }
    }
后台代码Mapper.xml文件代码:
<update id="decreStar">
        update blog_article
        set article_star_num = article_star_num - 1
        where id=#{id};
</update>

<update id="increStar">
        update blog_article
        set article_star_num = article_star_num + 1
        where id=#{id};
</update>

以上就是小一的代码分享啦!如果对小伙伴的开发有一定的作用,请点个赞再走哦~~

  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值