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

使用Fetch调用Django接口后,如何渲染带上下文的页面?

问题

我使用JavaScript进行表单验证,并通过Fetch调用Django后端API接口。后端视图处理请求后会渲染携带上下文的HTML页面,但当前响应仅返回给Fetch,无法直接在浏览器中渲染该页面。我曾尝试使用document.documentElement.innerHTML = data;来渲染视图返回的HTML,但未成功,且认为这并非最优方案,想了解如何正确渲染视图返回的带上下文的HTML页面。

相关代码

JavaScript表单验证及Fetch请求代码

try {
        const response = await fetch("/save_dependent", { // Ensure you replace "/save_dependent" with your actual endpoint
            method: "POST",
            headers: {
                "X-CSRFToken": document.querySelector('input[name="csrfmiddlewaretoken"]').value, // Pass the CSRF token in the request headers
                // Do not set 'Content-Type' manually; let the browser handle it for multipart/form-data boundary
            },
            body: formData,
        });
        if (response.ok) {
            let data = await response.text(); 
            console.log('Server Response:', data);

        } else {
            // Handle HTTP error responses (e.g., 400, 401, 403, 404, 500)
            console.error('Server responded with non-OK status:', response.status);
        }
        } catch (error) {
        console.error('Error:', error);
    }

Django视图代码(views.py)

@login_required(login_url='auth/signin')
def save_dependent(request):
    # print('request.data: ',request.data)
    print("POST data:")
    for key, value in request.POST.items():
        print(f"{key}: {value}")
    if request.method == 'POST':
        uploaded_file = request.FILES.get('dependent_docs')
        print('uploaded_file ',uploaded_file)
        if uploaded_file:
            # Handle file processing
            print(f"Received file: {uploaded_file.name}")
            save_path = os.path.join(SETTINGS.BASE_DIR, 'static', 'assets', 'img', 'beyond_border_dependents_doc', uploaded_file.name)
            try:
                # Writing the uploaded file to the specified directory
                with open(save_path, 'wb+') as destination:
                    for chunk in uploaded_file.chunks():
                        destination.write(chunk)
                print('returning....')
                return render(request, 'nhcp_registration_test.html',{'dependent_saved':'successs'})
                # return HttpResponse("File uploaded successfully")
            except Exception as e:
                # Handle exceptions that occurred during file upload
                print(f"Failed to upload file. Error: {e}")
                return HttpResponse("Failed to upload file.", status=500)
        else:
            print('in else of uploaded_file')
            return render(request, 'nhcp_registration.html',{'dependent_saved':'successs'})
    print('at last return')    
    return render(request, 'nhcp_registration_test.html')
解决方案

方案1:正确替换页面内容(适配后端返回HTML的场景)

你之前用document.documentElement.innerHTML = data失败,是因为直接修改<html>标签内容会触发浏览器解析限制,且原有页面资源可能失效。推荐两种可靠方式:

方式A:重新写入整个文档

这种方式让浏览器重新解析完整HTML,和直接打开页面效果一致:

if (response.ok) {
    let data = await response.text(); 
    console.log('Server Response:', data);
    // 重新写入并加载完整HTML
    document.open();
    document.write(data);
    document.close();
}

方式B:替换页面body内容

如果仅需更新页面主体部分,可直接替换<body>内容:

if (response.ok) {
    let data = await response.text(); 
    console.log('Server Response:', data);
    // 仅替换body内的内容
    document.body.innerHTML = data;
}

方案2:改为前后端分离模式(更优解)

若想让架构更清晰,建议后端不直接返回HTML,而是返回JSON格式的状态和上下文数据,由前端负责渲染页面:

修改Django视图返回JSON

from django.http import JsonResponse

@login_required(login_url='auth/signin')
def save_dependent(request):
    if request.method == 'POST':
        uploaded_file = request.FILES.get('dependent_docs')
        if uploaded_file:
            save_path = os.path.join(SETTINGS.BASE_DIR, 'static', 'assets', 'img', 'beyond_border_dependents_doc', uploaded_file.name)
            try:
                with open(save_path, 'wb+') as destination:
                    for chunk in uploaded_file.chunks():
                        destination.write(chunk)
                # 返回JSON数据,包含状态和跳转地址
                return JsonResponse({
                    'status': 'success',
                    'dependent_saved': 'successs',
                    'redirect_url': '/nhcp_registration_test/'
                })
            except Exception as e:
                print(f"Failed to upload file. Error: {e}")
                return JsonResponse({"error": "Failed to upload file."}, status=500)
        else:
            return JsonResponse({
                'status': 'success',
                'dependent_saved': 'successs',
                'redirect_url': '/nhcp_registration/'
            })
    return JsonResponse({"error": "Invalid request method"}, status=400)

前端根据JSON响应处理

try {
    const response = await fetch("/save_dependent", {
        method: "POST",
        headers: {
            "X-CSRFToken": document.querySelector('input[name="csrfmiddlewaretoken"]').value,
        },
        body: formData,
    });
    if (response.ok) {
        const result = await response.json();
        if (result.status === 'success') {
            // 跳转到指定页面
            window.location.href = result.redirect_url;
            // 或者前端自行渲染成功提示
            // document.body.innerHTML = `<div class="success">${result.dependent_saved}</div>`;
        }
    } else {
        const error = await response.json();
        console.error('Error:', error.error);
    }
} catch (error) {
    console.error('Request Error:', error);
}

方案3:直接使用表单默认提交(最简单)

如果不需要异步处理,直接用表单默认提交方式,后端返回的HTML会自动在浏览器中渲染:

<!-- 表单添加action和method -->
<form action="/save_dependent" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <!-- 表单字段 -->
    <button type="submit">提交</button>
</form>

内容的提问来源于stack exchange,提问作者Vinay yadav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:57:43