如何实现无独立HTML请求的点赞逻辑并解决405方法不允许错误
问题解决:改造文章点赞逻辑避免Google爬虫405错误
问题背景
现有文章点赞功能用<a>标签带真实跳转链接,Google爬虫爬取这些链接时会发起GET请求,但后端接口仅接受POST请求,导致返回「405 Method Not Allowed」错误。需要在保留所有现有功能(当日重复点赞限制、计数实时更新、按钮状态标记)的前提下,改造为无独立可爬链接且不依赖POST方法的实现。
改造方案
1. HTML改造:替换<a>为<button>,移除可爬链接
把原来的<a>标签换成<button>,用data-*属性存储文章ID和点赞类型,彻底避免爬虫抓取到可访问的点赞URL:
<button class="comments-sub-header__item like-button {{ $article->hasLikedToday('heart') ? 'active' : '' }}" data-article-id="{{ $article->id }}" data-like-type="heart"> <div class="comments-sub-header__item-icon-count"> {{ $article->getLikeHeartTotal() }} </div> </button> <button class="comments-sub-header__item like-button {{ $article->hasLikedToday('finger') ? 'active' : '' }}" data-article-id="{{ $article->id }}" data-like-type="finger"> <div class="comments-sub-header__item-icon-count"> {{ $article->getLikeFingerTotal() }} </div> </button>
2. PHP改造:调整接口为GET请求
原有Cookie判断逻辑已经能防止用户当日重复点赞,完全可以把接口改成接受GET请求,适配爬虫的请求方式:
路由调整(根据你的实际路由配置修改)
将原POST路由替换为GET路由:
// 原路由示例:Route::post('/article/{id}', [ArticleController::class, 'postLike']); Route::get('/article/like/{id}', [ArticleController::class, 'postLike'])->name('article.like');
控制器代码(仅微调,核心逻辑不变)
无需大幅改动,仅调整提示文案为更自然的中文,参数获取逻辑兼容GET请求:
public function postLike($id, Request $request) { $article = Article::find($id); if (!$article) { return abort(404); } $type = $request->input('type'); // input方法兼容GET/POST,无需修改 if ($article->hasLikedToday($type)) { return response() ->json( [ 'message' => "今天已经用{$type}给这篇文章点过赞了", ] ); } $cookie = $article->setLikeCookie($type); $article->increment("like_{$type}"); return response() ->json( [ 'message' => "成功用{$type}给文章{$article->id}点赞", 'cookie_json' => $cookie->getValue(), ] ) ->withCookie($cookie); }
注:Model中的
hasLikedToday和setLikeCookie方法完全无需修改,原有当日点赞限制逻辑正常生效。
3. JavaScript改造:基于data属性构造请求
修改JS逻辑,从按钮的data属性获取参数,构造GET请求URL,同时保留原有状态更新逻辑:
$(function() { $('.like-button').on('click', function(event) { event.preventDefault(); const targetElement = $(this); // 从data属性获取文章ID和点赞类型 const articleId = targetElement.data('article-id'); const likeType = targetElement.data('like-type'); // 已点赞状态直接返回,避免重复请求 if (targetElement.hasClass('active')) { return; } $.ajax({ url: `/article/like/${articleId}?type=${likeType}`, type: 'GET', success: function() { const counter = targetElement.find('.comments-sub-header__item-icon-count'); const current = parseInt(counter.html()); counter.html(current + 1); targetElement.addClass('active'); }, error: function(res) { // 处理重复点赞等错误情况 if (res.responseJSON?.message) { console.log(res.responseJSON.message); } } }); }); });
注:GET请求无需CSRF验证,可移除全局的CSRF头配置(若框架强制要求可保留)。
改造说明
- 无独立可爬链接:用
<button>替代<a>,去除真实href属性,爬虫无法抓取到点赞相关URL。 - 不依赖POST方法:改用GET请求,结合原有Cookie当日点赞限制逻辑,避免重复点赞的幂等性问题。
- 保留全部原有功能:当日点赞限制、计数更新、按钮激活状态标记等逻辑完全保留,用户体验无变化。
内容的提问来源于stack exchange,提问作者Hector
相关产品推荐
相关产品推荐

