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

前端用$.getJSON传含URL参数至Django后端遇404问题求助

解决Django接收含URL参数时的404错误

你的问题核心在于Django路由对路径参数的解析逻辑和URL编码后的处理冲突了,我来一步步帮你理清并解决:

为什么会出现404?

你前端用encodeURIComponent把URL转成了类似http%3A%2F%2Fexample.com的格式,但Django在处理请求URL时,会自动对整个URL进行URL解码——也就是说%2F会被还原成/。

而你定义的path路由里,<url>参数默认使用的是str转换器,这个转换器的规则是不匹配路径分隔符/。解码后的URL里的/会把原本的路径拆分成更多段,比如你的请求路径会变成:
/updateAssignment/1/xxx/2024/xxx/http://example.com/xxx/...
Django会把http:、//example.com当成单独的参数段,和你定义的12个参数的路由完全不匹配,自然就返回404了。

解决方案(按推荐程度排序)

方案1:改用查询字符串传递参数(最推荐)

把URL这类含特殊字符的参数从路径里移到查询字符串(GET参数)中,这是更符合HTTP规范的做法,也能彻底避免路径匹配问题。

后端修改urls.py:

简化路由,只保留必要的标识参数(比如assignmentId):

path("updateAssignment/<int:iD>/", Dashboard.update_assignment, name="updateAssignment")

前端修改JS代码:

不用手动拼接路径,直接用jQuery的getJSON的第二个参数传递键值对,jQuery会自动帮你编码参数:

function updateAssignment(assignmentId){
  const assignmentUpdateEndpoint = `/updateAssignment/${assignmentId}/`;
  // 把所有参数整理成对象
  const params = {
    body: document.getElementById(`Assignment-Body${assignmentId}`).value,
    deadline: document.getElementById(`Assignment-Deadline${assignmentId}`).value,
    user: document.getElementById(`Assignment-User${assignmentId}`).value,
    url: document.getElementById(`Assignment-URL${assignmentId}`).value,
    game: document.getElementById(`Assignment-Game${assignmentId}`).value,
    additionalKeywords: document.getElementById(`Assignment-Additional-Keywords${assignmentId}`).value,
    seoTitle: document.getElementById(`Assignment-SEOtitle${assignmentId}`).value,
    payment: document.getElementById(`Assignment-Payment${assignmentId}`).value,
    wordCount: document.getElementById(`Assignment-WordCount${assignmentId}`).value,
    category: document.getElementById(`Assignment-Category${assignmentId}`).value,
    state: document.getElementById(`Assignment-State${assignmentId}`).value
  };
  
  $.getJSON(assignmentUpdateEndpoint, params).done((response) => {
    // 处理响应逻辑
  });
}

后端视图获取参数:

在update_assignment视图里,通过request.GET获取参数:

def update_assignment(request, iD):
    url = request.GET.get('url')
    body = request.GET.get('body')
    # 其他参数同理...
    # 业务逻辑处理

方案2:使用正则路由(re_path)匹配含/的参数

如果你坚持要把URL放在路径参数里,可以用re_path自定义正则表达式,让<url>参数能匹配包含/的内容。

修改urls.py:

from django.urls import re_path

re_path(
    r"updateAssignment/(?P<iD>[^/]+)/(?P<body>[^/]+)/(?P<deadline>[^/]+)/(?P<user>[^/]+)/(?P<url>.+)/(?P<game>[^/]+)/(?P<aK>[^/]+)/(?P<seoTitle>[^/]+)/(?P<payment>[^/]+)/(?P<wordCount>[^/]+)/(?P<category>[^/]+)/(?P<state>[^/]+)/",
    Dashboard.update_assignment,
    name="updateAssignment"
)

这里(?P<url>.+)的正则会匹配任意字符(包括/),这样就能正确捕获解码后的完整URL参数。

⚠️ 注意:这个方案有个隐患——如果url参数后面的其他参数里也出现/,会导致参数匹配混乱,所以只适合你能确保后续参数不含/的场景。

方案3:自定义Django路径转换器

另一种更优雅的路径参数方案是自定义转换器,让它支持匹配包含/的内容:

  1. 在项目中创建custom_converters.py文件:
from django.urls.converters import StringConverter

class URLConverter(StringConverter):
    regex = r'.+'  # 匹配任意字符,包括路径分隔符/
  1. 在urls.py中注册并使用这个转换器:
from django.urls import path, register_converter
from .custom_converters import URLConverter

# 注册自定义转换器
register_converter(URLConverter, 'url')

# 修改路由,使用<url:url>来匹配URL参数
path(
    "updateAssignment/<iD>/<body>/<deadline>/<user>/<url:url>/<game>/<aK>/<seoTitle>/<payment>/<wordCount>/<category>/<state>/",
    Dashboard.update_assignment,
    name="updateAssignment"
)

这样<url:url>就会使用自定义的转换器,正确捕获包含/的URL参数。

总结

优先选择方案1(查询字符串),它不仅能解决当前的404问题,还让你的API设计更规范、更易维护。如果因为某些原因必须用路径参数,再考虑方案2或3。

内容的提问来源于stack exchange,提问作者Kamil Bialomazur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:20:15