You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中如何为带slug参数的URL编写JavaScript Fetch请求?

解决Django中Fetch API实现无刷新点赞的URL与CSRF问题

问题背景

作为Django和异步开发新手,正在优化留言板应用,希望用Fetch API实现无刷新点赞,目前卡在Fetch请求的URL构造(带slug参数)和CSRF令牌处理上。

一、正确构造Fetch请求的URL

你的PostLike视图URL规则为path('like/<slug:slug>/', ..., name='post_like'),有两种可靠的URL构造方式:

方式1:模板直接生成完整URL传递给JS

修改模板中按钮的onclick事件,把Django生成好的完整点赞URL传入函数,同时将按钮type改为button避免表单默认提交刷新页面:

<button class="btn-like" type="button" onclick="like('{% url 'post_like' post.slug %}')">

方式2:JS中用slug拼接URL

如果要在JS内拼接URL,先把帖子slug传递给函数:

<button class="btn-like" type="button" onclick="like('{{ post.slug }}')">

再在JS中构造URL:

function like(post_slug) {
    const url = `/like/${post_slug}/`; // 注意末尾斜杠要和urls.py中的规则匹配
    // 后续代码...
}

二、处理CSRF令牌

Django要求POST请求必须携带CSRF令牌,Fetch API需要手动将令牌添加到请求头:

步骤1:从Cookie中读取CSRF令牌

Django会将CSRF令牌存在页面Cookie中,通过以下工具函数获取:

function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

步骤2:在Fetch请求中添加CSRF头

修改Fetch配置,将令牌放入请求头:

const csrftoken = getCookie('csrftoken');
fetch(url, {
    method: "POST",
    headers: {
        'X-CSRFToken':': csrftoken,
        'Accept': 'application/json'
    }
})

三、完整代码修改示例

1. 帖子详情模板片段修改

<div class="row">
    <div class="col-1">
    {% if user.is_authenticated %}
        <strong>
            {% if liked %}
                <button class="btn-like" type="button" onclick="like('{% url 'post_like' post.slug %}')">
                    <i class="like-icon fas fa-thumbs-up"></i>
                </button>
                <span class="likes-count">{{ post.number_of_likes }}</span>
            {% else %}
                <button class="btn-like" type="button" onclick="like('{% url 'post_like' post.slug %}')">
                    <i class="like-icon far fa-thumbs-up"></i>
                </button>
                <span class="likes-count">{{ post.number_of_likes }}</span>
            {% endif %}
        </strong>
    {% else %}
        <strong class="text-secondary"><i class="far fa-thumbs-up"></i> <span class="likes-count">{{ post.number_of_likes }}</span></strong>
    {% endif %}
</div>

注:将id改为class,避免页面存在多个帖子时DOM选择器冲突

2. 完整JavaScript代码

function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

function like(url) {
    const csrftoken = getCookie('csrftoken');
    // 通过事件对象定位当前按钮对应的图标和计数元素
    const button = event.target.closest('.btn-like');
    const likeIcon = button.querySelector('.like-icon');
    const likeCount = button.nextElementSibling;

    fetch(url, {
        method: "POST",
        headers: {
            'X-CSRFToken': csrftoken,
            'Accept': 'application/json'
        }
    })
    .then(response => {
        if (!response.ok) throw new Error('请求失败');
        return response.json();
    })
    .then(data => {
        likeCount.textContent = data.likes;
        likeIcon.className = data.liked ? "like-icon fas fa-thumbs-up" : "like-icon far fa-thumbs-up";
    })
    .catch(() => alert("Unable to like/unlike post."));
}

3. 视图层无需修改

你的PostLike视图已正确返回JsonResponse,保持原样即可。

关键注意事项

  • 按钮必须设置type="button",避免触发表单默认提交行为
  • 多帖子页面不要用id选择DOM元素,改用class或事件对象定位
  • CSRF令牌必须从Cookie读取并添加到请求头,否则Django会拒绝请求
  • URL格式要和urls.py中的规则完全匹配(比如末尾的斜杠)

内容的提问来源于stack exchange,提问作者Mark Hewitt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 19:20:47