1

私は画像アップロードフォームに取り組んでいます。ユーザーが画像をアップロードしたとき。その画像をプレビュー領域に ajax で表示します...フォームはリロードされますが、新しいアバターを表示したくないようです。そして、CSRF verification failed. Request abortedエラーが発生します。

Reason given for failure: CSRF is missing or incorrect.

フォーム内に csrf_token があります。

テンプレート:

<form class="nice inline-form" enctype="multipart/form-data" method="POST" action="/profile/edit/" id="avatarLoadForm">
      <input type="hidden" name="next" value="/account/settings/">
      {% csrf_token %}
      <div>
      <label for="avatar">Avatar</label>
      <div id="preview" class="frame">  
           <img src="{% if profile.user %}{% thumbnail profile.avatar 120x120 crop %}{% else %}{{ DEFAULT_AVATAR }}{% endif %}" alt="" alt="sample-pic" id="thumb" />
      </div>
      <input type="file" size="20" id="imageUpload">
      and other form info...
</form>

Ajax/Jquery:

$(document).ready(function(){

        var thumb = $('img#thumb'); 

        new AjaxUpload('imageUpload', {
            action: $('#avatarLoadForm').attr('action'),
            name: 'avatar',
            csrfmiddlewaretoken: $( "#csrfmiddlewaretoken" ).val(),

            onSubmit: function(file, extension) {
                $('#preview').addClass('loading');
            },
            onComplete: function(file, response) {
                thumb.load(function(){
                    $('#preview').removeClass('loading');
                    thumb.unbind();
                });
                thumb.attr('src', response);

            } 

        });

私のViews.pyに欠けているものがあるかもしれません。

@login_required        
def edit_profile(request):
    context = base_context(request)
    if request.method == 'POST':
        notify = "You have successfully updated your profile."
        user_info_form = UserInfoForm(request.POST, request.FILES)
        if user_info_form.is_valid():
            if request.is_ajax():
                response = simplejson.dumps({"status": "Upload Success"})
                return HttpResponse (response, mimetype='application/json')
            messages.success(request, 'You have successfully updated your profile.')
            user_info_form.save(request.user, profile_type)
            return HttpResponseRedirect(request.POST.get('next', '/profile/' + request.user.username + '/'))
    else:
        initial = {}
        initial['first_name'] = request.user.first_name
        initial['last_name'] = request.user.last_name
        initial['email'] = request.user.email
        initial['about'] = profile.about
        initial['country'] = profile.country
        initial['about'] = profile.about
        user_info_form = UserInfoForm(initial=initial)
    context['user_info_form'] = user_info_form
    context['profile'] = profile
    return render_to_response('settings/profile.html', context, context_instance=RequestContext(request))

設定.py:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.csrf.CsrfResponseMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'pagination.middleware.PaginationMiddleware',
)

ファイルのアップロードは、ajax がらくたなしで機能します。言うまでもなく、実際には画像が保存されますが、プレビューには表示されません。何が問題なのか、なぜこれが起こっているのか、私には本当にわかりません。csrf の失敗に関する投稿がたくさんあります。しかし、私はこの状況に関連するものを見つけることができません。どんな洞察も非常に高く評価されます。

4

4 に答える 4

3

csrf トークンに id があると思う理由は何#csrfmiddlewaretokenですか? レンダリングされた html をざっと見てみると、テンプレート タグが id 属性を生成していないことがわかります。

$("input[name=csrfmiddlewaretoken]").val()代わりに試す

于 2012-05-01T22:19:55.260 に答える
0

これは私のために働く:

beforeSend: function(jqXHR, settings) {
    jqXHR.setRequestHeader('X-CSRFToken', $('input[name=csrfmiddlewaretoken]').val());
},

または、次のように dom から Cookie を抽出することもできます。これは、フォームが ajax を介して生成され、レンダリング方法が原因で {{ csrf_token }} を送信できない場合に最適です。

beforeSend: function(xhr, settings) {
        console.log('-------------before send--');
        function getCookie(name) {
            var cookieValue = null;
            if (document.cookie && document.cookie != '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
        }
        if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
            // Only send the token to relative URLs i.e. locally.
            xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
        }
} 
于 2013-02-14T00:06:27.117 に答える
0

これを参照してくださいhttp://djangolinks.com/detail/ajax-post-requests-csrf-fix-69/

于 2012-05-02T07:02:02.093 に答える
0
csrfmiddlewaretoken: $( "#csrfmiddlewaretoken" ).val(),

これはおそらくうまくいきません。CSRF フィールドの名前/ID は動的に生成され、このような静的な文字列ではありません。

AJAX リクエストで CSRF ミドルウェアを適切に使用する方法については、https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajaxを参照してください。

于 2012-05-01T22:15:26.130 に答える