2012-02-22 12 views
21

क्या यह जांचने का एक "सुरक्षित" तरीका है कि वास्तव में AJAX विधियों का उपयोग करने से पहले एक ही मूल नीति URL पर लागू होती है या नहीं? यहाँ मैं क्या है:जांचें कि क्या मूल उत्पत्ति लागू होती है

function testSameOrigin(url) { 

    var loc = window.location, 
     a = document.createElement('a'); 

    a.href = url; 

    return a.hostname == loc.hostname && 
      a.port == loc.port && 
      a.protocol == loc.protocol; 
} 

काम करता है इस तरह की है, लेकिन यह एक मैनुअल wikipedia article के आधार पर अनुमान की तरह है। पूर्व-जांच क्रॉस डोमेन भत्ता का कोई बेहतर तरीका है? jQuery उपयोग करने के लिए ठीक है।

+0

यदि आप एक क्रॉस डोमेन अनुरोध करते हैं तो यह 'readystate = 4' और' statuscode = 0' के साथ विफल हो जाएगा, जो निरस्त अनुरोध के समान है। चूंकि आपको निरस्त अनुरोधों के खिलाफ सुरक्षा करने की आवश्यकता है, फिर भी आपको इस चेक की आवश्यकता क्यों होगी? मुझे लगता है कि इस सुरक्षा उपाय को बाहर से लागू किया गया है, आपके पास इसका कोई नियंत्रण नहीं है, इसलिए पर्यावरण के भीतर से कोई भी जांच परिभाषा गलत है। इसलिए मुझे नहीं लगता कि आपको कभी इसकी जांच करनी चाहिए, बस अनुरोध विफल होने दें। – Halcyon

उत्तर

8

दिलचस्प सवाल! मैंने चारों ओर खोज की और आपके द्वारा पोस्ट की गई चीज़ों के अलावा कुछ भी नहीं मिला, लेकिन जब मैं कुछ टेस्ट कोड के साथ गड़बड़ कर रहा था तब मैं इस पर आया था। यदि आप अनुरोध किए बिना यूआरएल का परीक्षण करने का एक आसान तरीका चाहते हैं, तो मैं इसे वही करूँगा जिस तरह से आप इसे कर रहे हैं। आप परीक्षण करने के लिए एक अनुरोध बनाने के बारे में परवाह नहीं है, तो आप इस कोशिश कर सकते:

जो कुछ यूआरएल आप चाहते हैं के लिए एक सरल ajax अनुरोध करें:

var ajaxRequest = $.ajax({ 
    url: 'http://www.google.com', 
    async: false 
}); 

जो एक jqXHR ऑब्जेक्ट, जिसे फिर आप कर सकते हैं जाँच:

ajaxRequest.isRejected(); // or... 
ajaxRequest.isResolved(); 

अब, इस के साथ ही समस्या यह है कि isRejected() हर एक मामले में जहां पेज लोड नहीं करता है (यानी 404 नहीं मिला, आदि) के लिए true करने का मूल्यांकन करेंगे है, लेकिन आप स्थिति देख सकते हैं कोड:

ajaxRequest.status; 

ऐसा लगता है कि इसके बाद के संस्करण लाइन की तरह 0 वापस आ जाएगी जब आप एक ही मूल नीति को तोड़ने के लिए प्रयास करते हैं, लेकिन यह अन्य मामलों में उचित त्रुटि कोड (फिर से, अर्थात 404) वापस आ जाएगी। किसी भी तरह से

function testSameOrigin(testUrl) { 

    var ajaxRequest = $.ajax({ 
    url: testUrl, 
    async: false 
    }); 

    return ajaxRequest.isRejected() && ajaxRequest.status === 0; 
} 

नहीं एक निश्चित जवाब है, लेकिन मुझे आशा है कि यह आपकी मदद करता है यह पता लगाने के लिए आप क्या देख रहे हैं:

तो लपेट के लिए, हो सकता है आप की तरह कुछ कर रही कोशिश कर सकते!

+0

हां, यह एक दिलचस्प दृष्टिकोण है। मेरे मूल मामले में, मैं यूआरएल को "मान्य" करने की कोशिश करके अस्वीकृत AJAX कॉल करते समय आपको प्राप्त होने वाली ग़लत कंसोल त्रुटियों से छुटकारा पाना चाहता था। मैंने हाल ही में पाया है कि एक स्थानीय फ़ाइल (फ़ाइल: प्रोटोकॉल) पर AJAX अनुरोध करने से भी हर बार विफल रहता है। तो यह जांचने का एक और मामला है ... – David

+0

आप 'isLocal' ध्वज को 'true' http://api.jquery.com/jQuery पर सेट करके स्थानीय फ़ाइलों के लिए AJAX का उपयोग कर सकते हैं।AJAX/# jQuery-AJAX-सेटिंग्स – Steve

0

क्रॉस डोमेन स्क्रिप्ट निष्पादित करने का एक और तरीका JSON-P का उपयोग कर रहा है। आप यह article भी पढ़ सकते हैं। अन्यथा, एक ही मूल नीति द्वारा क्रॉस डोमेन स्क्रिप्टिंग की अनुमति नहीं है।

+0

मुझे यकीन नहीं है कि क्यों सभी उत्तर क्रॉस-ब्राउज़र AJAX अनुरोधों को बनाने या बनाने के बारे में नहीं हैं, जो मैं पूछ रहा हूं, बिल्कुल नहीं है ... क्या मुझे और स्पष्ट होने की आवश्यकता है? – David

10

क्या यह जांचने का एक "सुरक्षित" तरीका है कि वास्तव में AJAX विधियों का उपयोग करने से पहले एक ही मूल नीति किसी URL पर लागू होती है या नहीं? यहाँ मैं क्या है:

function testSameOrigin(url) { 

    var loc = window.location, 
     a = document.createElement('a'); 

    a.href = url; 

    return a.hostname == loc.hostname && 
      a.port == loc.port && 
      a.protocol == loc.protocol; 
} 

यह बात करने का एक सुरक्षित और विश्वसनीय तरीका है, बशर्ते आप कर रहे हैं (या बल्कि नहीं कर) कुछ बातें है।

इस प्रकार के काम, लेकिन यह विकिपीडिया लेख के आधार पर एक मैनुअल अनुमान है।

यह पूरी तरह से "सामान्य" परिस्थितियों में काम करना चाहिए। यदि आप cross-domain scripting का उपयोग करने की योजना बना रहे हैं तो इसे संशोधित करने की आवश्यकता होगी।

यदि आप अपनी स्क्रिप्ट में document.domain संशोधित करते हैं, उदाहरण के लिए "foo.example.com" और "bar.example.com" से "उदाहरण" में।कॉम http://example.com ", जहां वास्तव में यह true लौटना चाहिए" अपने testSameOrigin समारोह के लिए false वापसी होगी "।

आप document.domain को संशोधित करने पर योजना बना रहे हैं, तो आप बस जोड़ सकते हैं अपनी स्क्रिप्ट में उस के लिए एक जांच जोड़ें।

यदि आप क्रॉस-डोमेन संचार की अनुमति देने के लिए सीओआरएस (उपर्युक्त लिंक देखें) का उपयोग करने की योजना बना रहे हैं, तो यह झूठी नकारात्मक भी लौटाएगा। लेकिन यदि आप सीओआरएस का उपयोग कर रहे हैं, तो आपके पास डोमेन की एक सूची होगी जिसके साथ आप संवाद कर सकते हैं, और आप उस सूची में भी इस सूची को जोड़ सकते हैं।

क्या प्री-चेकिंग क्रॉस डोमेन भत्ता का बेहतर तरीका है? jQuery उपयोग करने के लिए ठीक है।

शायद नहीं

, हालांकि यह उल्लेख के लायक है कि आप क्या स्टीव जवाब से कंसोल में देख रहे हैं "पर्यवेक्षक के दुविधा" ... उन त्रुटियों देखो की तरह वे का निरीक्षण करने की कोशिश कर कंसोल से उत्पन्न कर रहे हैं हो सकता है हो सकता है अन्य खिड़की, लिपि से जरूरी नहीं है।

मान लें कि आप document.domain के साथ गड़बड़ नहीं कर रहे हैं या सीओआरएस का उपयोग कर रहे हैं, तो आपका मूल समाधान शायद बेहतर है, क्योंकि यह निर्धारित करने के लिए अतिरिक्त अनुरोध करने की आवश्यकता नहीं है कि सर्वर उपलब्ध है या नहीं। भले ही आप कुछ क्रॉस-डोमेन स्क्रिप्टिंग कर रहे हों, फिर भी आपके पास समायोजित करने के लिए आपके पास फ़ंक्शन को संशोधित करना शायद आपकी सबसे अच्छी शर्त है।

+1

जबकि यह सीओआरएस अनुरोधों की जांच करने का एक अच्छा तरीका है, यह आईई 7 पर टूट जाता है जबकि एंकर उत्पन्न लिंक के बारे में कोई जानकारी नहीं लौटाएगा, उदाहरण के लिए आईई 7 में इस तरह के '' लिंक का मूल्यांकन करना 'a.href =>" main.html "' 'a.hostname =>" "' 'आदि वापस आ जाएगा। मैं अभी भी यह पता लगाने की कोशिश कर रहा हूं कि आईई 7 में इस से कैसे निपटें। लेकिन कोई अच्छा समाधान नहीं मिला। चूंकि यह पूर्ण href कभी नहीं बनाएगा। – zanona

+0

क्या दस्तावेज़.डोमेन चेक आप जोड़ देंगे? 'Document.domain' के साथ 'loc.hostname' को बस बदलना सही होगा? –

+0

@BT 'a.hostname' अभी भी" foo.example.com "होगा और 'document.domain'" example.com "होगा। इसे एक विशेष केस चेक होना होगा, यानी यदि आप जानते हैं कि आप 'document.domain' से "example.com" दोनों को फिर से लिख रहे हैं, तो होस्टनाम चेक 'a.hostname == loc.hostname || a.hostname == "foo.example.com" ' –

0

बिल्डिंग Dagg Nabbit के जवाब से दूर है, यह एक छोटे से अधिक पूरा लगता है:

function sameOrigin(url) { 
    var loc = window.location, a = document.createElement('a') 
    a.href = url 

    return a.hostname === loc.hostname && 
      a.port === loc.port && 
      a.protocol === loc.protocol && 
      loc.protocol !== 'file:' 
} 

चेतावनियां मैं के बारे में सोच सकते हैं:

  • खाता
  • नहीं करता है में document.domain नहीं ले करता है CORS को
  • आई 7 में काम नहीं करता है (जैसा कि ज़ोनोना द्वारा उल्लिखित है)
  • खराब नहीं है अजीब वातावरण (एंड्रॉयड) की तरह है जहाँ आप पहुँच मनमाना file:// प्रोटोकॉल रास्तों कर सकते हैं (किसी व्यक्ति ने इस का सत्यापन करें, एंड्रॉयड के बारे में जानकारी https://security.stackexchange.com/questions/25138/same-origin-policy-for-file-urls-in-android-browser पुराना हो सकता है)
1

में k के साथ-साथ इस समाधान का प्रयास करें।

function csrfSafeMethod(method) { 
    // these HTTP methods do not require CSRF protection 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
} 

function sameOrigin(url) { 
    // test that a given url is a same-origin URL 
    // url could be relative or scheme relative or absolute 
    var host = window.document.location.host; // host + port 
    var protocol = window.document.location.protocol; 
    var srOrigin = '//' + host; 
    var origin = protocol + srOrigin; 
    // Allow absolute or scheme relative URLs to same origin 
    return (url === origin || url.slice(0, origin.length + 1) === origin + '/') || 
    (url === srOrigin || url.slice(0, srOrigin.length + 1) === srOrigin + '/') || 
    // or any other URL that isn't scheme relative or absolute i.e relative. 
    !(/^(\/\/|http:|https:).*/.test(url)); 
} 

// if you want to check before you make a call 
if (!csrfSafeMethod(data.type) && sameOrigin(data.url)) { 
    // ... 
} 

// or if you want to set csrf token 
$.ajax({ 
    beforeSend: function (xhr, settings) { 
    if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { 
     xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken")); 
    } 
    } 
}); 
संबंधित मुद्दे