XMLHttpRequest上传canvas图片到Django后服务器重定向不生效如何处理?
问题原因
你使用XMLHttpRequest发送异步请求时,后端返回的302重定向只会被XHR在后台自动跟随、请求跳转后的资源,不会触发浏览器顶层页面的跳转,所以看不到预期的页面切换效果。
可选解决方案
方案1:后端返回跳转地址,前端手动跳转(对现有代码改动最小)
第一步:修改Django视图
将原有重定向逻辑改为返回JSON格式的跳转地址:
# 顶部导入依赖 from django.http import JsonResponse from django.urls import reverse def create (request, id): artwork = get_object_or_404(Artwork, pk=id) context = {'artwork' : artwork} if request.method == 'POST': form = ArtworkForm2(request.POST, request.FILES) if form.is_valid(): newChild = Artwork() newChild.parent = artwork newChild.artwork_img = form.cleaned_data['artwork_img'] newChild.artwork_title = form.cleaned_data['artwork_title'] newChild.ancestors = artwork.ancestors+1 newChild.save() newChild.updateAncestors() # 替换原有redirect逻辑,返回跳转地址 return JsonResponse({ "status": "success", "redirect_url": reverse('showwork', args=[newChild.id]) }) else: # 错误场景也返回结构化信息 return JsonResponse({ "status": "error", "msg": form.errors.as_text() }, status=400) else: form = ArtworkForm2() context.update({'form' : form}) return render(request, 'exp/create.html', context)
第二步:修改前端JS,添加请求响应监听
function submitFunction() { canvas = document.getElementById('myCanvas'); var dataURL = canvas.toDataURL("image/jpeg"); form = document.getElementById('myForm'); formData = new FormData(form); blob = dataURItoBlob(dataURL); url = window.location.href; xhr = new XMLHttpRequest(); xhr.open('POST', url, true); formData.set('artwork_img', blob, 'artwork.jpeg'); // 添加响应处理逻辑 xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { const res = JSON.parse(xhr.responseText); if (res.status === 'success') { // 手动触发页面跳转 window.location.href = res.redirect_url; } else { alert('提交失败:' + res.msg); } } else { alert('请求出错,状态码:' + xhr.status); } } xhr.send(formData); }
方案2:直接提交表单,复用原有重定向逻辑
不需要改动后端代码,只需把前端的XHR异步提交改为传统表单提交,后端返回的重定向就会自动生效:
function submitFunction() { canvas = document.getElementById('myCanvas'); var dataURL = canvas.toDataURL("image/jpeg"); form = document.getElementById('myForm'); blob = dataURItoBlob(dataURL); // 把canvas生成的图片转为File对象添加到表单 const imgFile = new File([blob], 'artwork.jpeg', {type: 'image/jpeg'}); const hiddenInput = document.createElement('input'); hiddenInput.type = 'file'; hiddenInput.name = 'artwork_img'; hiddenInput.files = [imgFile]; hiddenInput.style.display = 'none'; form.appendChild(hiddenInput); // 直接提交表单 form.submit(); }
内容的提问来源于stack exchange,提问作者erikt
相关产品推荐
相关产品推荐

