一、功能分析
该功能是在个人博客项目开发的过程中遇到的一个技术难点,该博客项目是一个基于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>
以上就是小一的代码分享啦!如果对小伙伴的开发有一定的作用,请点个赞再走哦~~