仅在IE9上提交django表单的HTTP 403

时间:2012-11-20 13:31:16

标签: django internet-explorer nginx

我正在研究Django 1.4.2版。 我已经实现了这个简单的表单示例(灵感来自djangobook):

# views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.mail import send_mail
from mysite.contact.forms import ContactForm

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            send_mail(
                cd['subject'],
                cd['message'],
                cd.get('email', 'noreply@example.com'),
                ['siteowner@example.com'],
            )
            return HttpResponseRedirect('/contact/thanks/')
    else:
        form = ContactForm()
    return render(request, 'contact_form.html', {'form': form})

# contact_form.html

<html>
<head>
    <title>Contact us</title>
</head>
<body>
    <h1>Contact us</h1>

    {% if form.errors %}
        <p style="color: red;">
            Please correct the error{{ form.errors|pluralize }} below.
        </p>
    {% endif %}

    <form action="" method="post">
        <table>
            {{ form.as_table }}
            {% csrf_token %}
        </table>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

# forms.py

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField()
    email = forms.EmailField(required=False)
    message = forms.CharField()

我尝试过的所有浏览器(chrome,maxthon,firefox)都能正常运行,但在IE9中,我收到了HTTP 403拒绝。

有关导致这种情况的任何线索?

编辑:经过深入调查后,我发现问题来自于:当询问空表格时,导航器会收到csrf cookie,但由于未知原因,它在发布表单时不会发回这个cookie。这个问题似乎只有当cookie来自pythonanywhere.com的nginx服务器时才出现,当我从我自己的apache服务器测试时,cookie被发送回来。

以下是从服务器捕获的两个标头:

HTTP/1.1 200 OK
Server: nginx/1.2.5
Date: Wed, 21 Nov 2012 13:56:31 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Cookie
Set-Cookie: csrftoken=1AJjzkbUgJdKAmkbiHicJ3or2Mfi6AbD; expires=Wed, 20-Nov-2013 13:56:31 GMT; Max-Age=31449600; Path=/

HTTP/1.1 200 OK
Date: Wed, 21 Nov 2012 13:56:50 GMT
Server: Apache/2.2.15 (CentOS)
Vary: Cookie
Set-Cookie:  csrftoken=2iMZSH1s0vJnEt4tRRY7FciT1Q7orrVF; expires=Wed, 20-Nov-2013 13:56:50 GMT; Max-Age=31449600; Path=/
Keep-Alive: timeout=180, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

唯一显着的差异似乎是来自apache的Kee-Alive标题...

你认为它可以来自那里吗?

2 个答案:

答案 0 :(得分:2)

{% csrf_token %}输出一个<input type="hidden" ...>标签,IE9可能会忽略它,因为它是表的直接子节点,而不是在单元格内。

尝试在{% csrf_token %}

旁边移动<input type="submit" value="Submit">

答案 1 :(得分:0)

在Django的机票#17157中,它表示问题在于Internet Explorer默认阻止第三方Cookie。因此,您可以为所有网站启用第三方Cookie,或仅在浏览器设置中为您的网站启用第三方Cookie。 以下是如何在IE 7(来自this link)中执行此操作:

  1. 点击&#34;工具&#34;菜单
  2. 点击&#34;互联网选项&#34;
  3. 选择&#34;隐私&#34;标签
  4. 选项1:为所有网站启用第三方Cookie

    1. 点击&#34;高级&#34;
    2. 选择&#34;覆盖自动Cookie处理&#34;
    3. 选择&#34;接受&#34;按钮&#34;第三方Cookie&#34;然后单击&#34;确定&#34;
    4. OR

      选项2:仅为Feedjit.com启用第三方Cookie

      1. 点击&#34;网站&#34;
      2. 添加&#34; your-domain.com &#34;然后单击&#34;允许&#34;
      3. 点击&#34;确定&#34;
      4. 选择&#34;接受&#34;按钮&#34;第三方Cookie&#34;然后单击&#34;确定&#34;