簡體   English   中英

使用 Ajax 發布到 Django 視圖時的 Http302 響應

[英]Http302 Response when using Ajax to post to Django view

我正在嘗試構建一個使用 ajax 接受輸入的網絡應用程序。 輸入在服務器端發送到 Django,我很難讓 URL 正確重定向。 我了解目前的問題與 django 翻譯應用程序有關。

這是相關部分。

阿賈克斯

 $(document).ready(function(){
  $('#applicant_form').on('submit', function(event){
    event.preventDefault() //this will stop the file from submitting the form manually.
    $.ajax({
        url :'/save_applicant/', // the endpoint
        type : "POST", // http method
        data : { the_post : "Yay" }, // data sent with the post request
        dataType: "json",
        // handle a successful response
        success : function(json) {
            console.log("success"); // another sanity check
        },

        // handle a non-successful response
        error : function(xhr,errmsg,err) {
            $('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
                " <a href='#' class='close'>&times;</a></div>"); // add the error to the dom
            console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
        }
    });
  });
});

HTML/DJANGO 模板

<form method = "POST" action = "" class="form bgform" id="applicant_form">
    {% csrf_token %}
    {{ applicant_form|crispy }}
    <input class="btn btn-default" type="submit" name="Save" />
</form>

視圖.py

def save_applicant(request):
if request.method =='POST':
    id = None
    if 'applicant' in request.session:
        id = request.session['applicant']

    applicant_form = ApplicantForm(request.POST)
    if applicant_form.is_valid():
        session_applicant  = applicant_form.save(commit=False)
        if id:
            session_applicant.id = id
        else:
            session_applicant.save()
            request.session['applicant'] = session_applicant.id 
        return HttpResponse(json.dumps({'status':'applicant_saved'}), content_type='application/json')

    else:
        return HttpResponse(applicant_form.errors.as_json(),content_type='application/json')

else:
    return HttpResponse(json.dumps({'status':'not_post'}),content_type='application/json')

網址.py

from django.conf.urls import include, url
from django.contrib import admin
from django.conf.urls.i18n import i18n_patterns

urlpatterns = [
]
urlpatterns += i18n_patterns(
    url(r'^$', 'plan_b_profile.views.home', name='home'),
    url(r'^save_applicant/','plan_b_profile.views.save_applicant',name='save_applicant'),
    url(r'^admin/', include(admin.site.urls)),
)

命令行

[21/Aug/2015 20:53:43]"POST /save_applicant HTTP/1.1" 302 0
[21/Aug/2015 20:53:43]"GET /en/save_applicant/ HTTP/1.1" 200 22 <---- HOW TO FIX THIS

再次感謝!

我認為這個問題的最佳解決方案是在 JavaScript 中動態分配 post url。

重寫您的模板,以便您可以將 django 反轉的 URL 存儲在某個地方,例如在表單的action中:

<form method = "POST" action="{% url "save_applicant" %}" class="form bgform" id="applicant_form">
    {% csrf_token %}
    {{ applicant_form|crispy }}
    <input class="btn btn-default" type="submit" name="Save" />
</form>

並將 AJAX 發布到該 URL 而不是靜態 URL,它將已經帶有語言前綴,因此不會發生重定向:

$(document).ready(function(){
  $('#applicant_form').on('submit', function(event){
    event.preventDefault() //this will stop the file from submitting the form manually.
    $.ajax({
        url :$(this).attr('action'), // the endpoint
        type : "POST", // http method
        data : { the_post : "Yay" }, // data sent with the post request
        dataType: "json",
        // handle a successful response
        success : function(json) {
            console.log("success"); // another sanity check
        },

        // handle a non-successful response
        error : function(xhr,errmsg,err) {
            $('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
                " <a href='#' class='close'>&times;</a></div>"); // add the error to the dom
            console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
        }
    });
  });
});

所以我離開了這個問題並意識到我的愚蠢錯誤。 我只是將我的 urls.py 更改為以下內容:

from django.conf.urls import include, url
from django.contrib import admin
from django.conf.urls.i18n import i18n_patterns

urlpatterns = [
    url(r'^save_applicant/','plan_b_profile.views.save_applicant',name='save_applicant'),
]
urlpatterns += i18n_patterns(
    url(r'^$', 'plan_b_profile.views.home', name='home'),
    url(r'^admin/', include(admin.site.urls)),
)

即使使用您自己的解決方案,當您使用 i18n 語言擴展時,如果您從視圖中返回 404 Not Found 狀態,您仍然可能會發現您收到 302 重定向。 當某些請求參數不正確時,我會這樣做(我對 HTTP GET 和 HTTP/AJAX POST 使用相同的視圖)。

原因是一些 Django 中間件(我認為是 LocaleMiddleware)會在中間件堆棧向上的過程中處理響應,看到頁面沒有被找到,並返回一個帶有瀏覽器語言前綴的 302 重定向。 然后,當下一個請求(在這種情況下)又找不到它時,您將收到不同的 404 Not Found 響應。 這很糟糕,因為您永遠無法看到原始請求失敗的原因。

在您的情況下,您可以通過執行以下操作來解決此問題:

...
urlpatterns = [
    url(r'^en/save_applicant/','plan_b_profile.views.save_applicant',name='save_applicant'),
]
...

這使有問題的中間件誤認為它已經是一個特定於語言的頁面(實際上是因為您在按鈕和 ajax 中返回了英語)。

您還可以使用solid-i18n-url 之類的解決方案完全刪除重定向。

編輯:但是經過反思,首先返回這樣的 404 可能是個壞主意; 400 Bad Request 會更好..

對於它的價值,我在 Django 的 HTTP 302 響應中遇到了同樣的問題。 如果 URL 中沒有斜杠,Django 將返回 HTTP 302(我在模板代碼中確實看到了斜杠,但 Django 日志講述了一個不同的故事):

[21/Aug/2015 20:53:43]"POST **/save_applicant** HTTP/1.1" 302 0

確保 URL 末尾的斜杠(即 /save_applicant**/**)應該可以使其工作。

@GwynBleidD 的回答,建議使用內置的 {% url %} 模板。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM