2011-10-13 18 views
13

コンテキスト:クロムのブラウザ拡張機能は、JQueryを使用してリモートのdjangoアプリケーションからの応答を要求します。 DjangoはリクエストがAJAX経由で行われ、 "Hello AJAX!"と応答することを認識します。私は自分の運動をthis great exampleから外しています。このリクエストはクロムエクステンションから行われているため、リクエストはクロスサイトで行われていますので、Djangoビューに@CSRF_exemptデコレータを使用しました。DjangoはJQueryのAJAXリクエストでis_ajaxがfalseであると言います

問題:私のDjangoのビューは、AJAX要求として要求を認識しておらず、代わりにHello AJAX!応答のそれはHello not AJAX!を応答します。

私のDjangoのビュー:
(URL /xhr_testは、次のビューを使用しています)

@csrf_exempt 
def check_login_extension(request): 
    if request.is_ajax(): 
     message = "Hello AJAX!" 
    else: 
     message = "Hello not AJAX" 
    return HttpResponse(message) 

私のjQueryの要求:

function xhrconnect() { 
    $.get("http://localhost:8000/xhr_test", function(data) { 
     document.getElementById('xhrmsg').innerHTML = (data); 
    }); 
} 
+0

「http:// localhost:8000/xhr_test /」というURLに後続のスラッシュを追加してみてください。 –

+0

試してみましたが効果はありません。 JQueryが後続のスラッシュを必要とするAJAXリクエストを送信する方法がありますか?ビューが 'Hello not AJAX'というメッセージで応答しているので、'/xhr_test'が正しいビューに正しく解決されていることがわかります。 JQueryが正しいURLを見つけられなかった場合、メッセージはまったくありません。 – jchung

答えて

15

jQueryのソースを通って行く、それがどのように見えます$.ajax()(したがって、$.get(),$.post()など)は自動化されますcrossDomainオプションをtrueに設定すると、ドメイン間のリクエストが行われていることがわかります(relevant code here)。実際のAJAXリクエストでは、crossDomainが設定されている場合、is_ajax()にはDjangoが必要とするヘッダHTTP_X_REQUESTED_WITHが設定されません(relevant code here)。

私はこの問題を解決する最も簡単な方法は、明示的falsecrossDomainを設定することであると思う:

function xhrconnect() { 
    $.ajax({ 
     url: "http://localhost:8000/xhr_test", 
     success: function(data) { 
      document.getElementById('xhrmsg').innerHTML = (data); 
     }, 
     crossDomain: false 
    }); 
} 

問題が解決しない場合は、手動要求にHTTP_X_REQUESTED_WITHヘッダーを設定するAJAX prefilter functionを使用して試みることができます。

+0

これは根本的な問題の良い説明です。 crossDomainをfalseに設定しようとしましたが、問題は解決しませんでした。私は、(a)synaxが正しくないか、(b)破損が既に行われていること、そしてその事実が 'HTTP_X_REQUESTED_WITH'ヘッダをリセットしなかった場合にcrossDomainをfalseに設定していることを推測しています。その他の潜在的な問題?私は来週何らかの点でAJAXプレフィルタ機能を試し、元に戻します。 – jchung

+2

それがうまくいかない理由がわかりません - リクエストヘッダを調べる方法がわかりませんが、オプションを正しく設定しているようです:http://jsfiddle.net/nrabinowitz/MYSDd/2/。もう1つのオプションは、 '{。" X-Requested-With ":" XMLHttpRequest "}]'をオプションとして、あるいは '$ .ajaxSetup()'に渡すことです。 – nrabinowitz

+0

私はパーティーに遅刻していることは知っていますが、ローカルホストドメインからローカルホストドメインに向いている場合、これはなぜcrossDomainと見なされますか? – babonk

0

this pageをご覧ください。 Djangoはクロスサイトリクエストフォージェリー(CSRF)に対する保護を提供するため、特別なAJAX設定が必要です。

$(document).ajaxSend(function(event, xhr, settings) { 
    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; 
    } 
    function sameOrigin(url) { 
    // url could be relative or scheme relative or absolute 
    var host = document.location.host; // host + port 
    var protocol = document.location.protocol; 
    var sr_origin = '//' + host; 
    var origin = protocol + sr_origin; 
    // Allow absolute or scheme relative URLs to same origin 
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || 
     (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || 
     // or any other URL that isn't scheme relative or absolute i.e relative. 
     !(/^(\/\/|http:|https:).*/.test(url)); 
    } 
    function safeMethod(method) { 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
    } 

    if (!safeMethod(settings.type) && sameOrigin(settings.url)) { 
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); 
    } 
}); 
+0

OPがビューで '@ csrf_exempt'デコレータを使用している場合、これはまだ問題ですか? – nrabinowitz

+0

それは、わかりません。私はそれを調べますが、上記のjavascriptコードが含まれるまで、ajaxリクエストに問題があることを覚えており、その答えが価値があると考えました。 – NT3RP

+0

このコードで何が起こっているのかを正確に理解するのはちょっと難しいです(自分のせいではなく自分のせいです)。このセットアップがどのように動作するか説明してください。w.r.t. DjangoのCSRF保護? – jchung

関連する問題