प्रवेश-नियंत्रण-अनुमति-मूल को कैसे बायपास करें?


197

मैं अपने स्वयं के सर्वर पर एक प्लेटफॉर्म पर अजाक्स कॉल कर रहा हूं, जिसे उन्होंने इन अजाक्स कॉल को रोकने के लिए सेट किया है (लेकिन मुझे अपने सर्वर के डेटाबेस से पुनर्प्राप्त डेटा प्रदर्शित करने के लिए अपने सर्वर से डेटा प्राप्त करने की आवश्यकता है)। मेरी अजाक्स स्क्रिप्ट काम कर रही है, यह डेटा को मेरे सर्वर की php स्क्रिप्ट पर भेज सकती है ताकि इसे प्रोसेस किया जा सके। हालाँकि इसे संसाधित डेटा वापस नहीं मिल सकता क्योंकि यह अवरुद्ध है"Access-Control-Allow-Origin"

मुझे उस प्लेटफ़ॉर्म के स्रोत / कोर तक कोई पहुंच नहीं है। इसलिए मैं स्क्रिप्ट को हटा नहीं सकता कि वह मुझे ऐसा करने के लिए मना कर रही है। (पी / एसआई ने Google Chrome के कंसोल का उपयोग किया और इस त्रुटि का पता लगाया)

अजाक्स कोड नीचे दिखाया गया है:

 $.ajax({
     type: "GET",
     url: "http://example.com/retrieve.php",
     data: "id=" + id + "&url=" + url,
     dataType: 'json',   
     cache: false,
     success: function(data)
      {
        var friend = data[1];              
        var blog = data[2];           
        $('#user').html("<b>Friends: </b>"+friend+"<b><br> Blogs: </b>"+blog);

      } 
  });

या JSONऊपर ajax स्क्रिप्ट के लिए एक समान कोड है? मुझे लगता JSONहै कि अनुमति है।

मुझे उम्मीद है कि कोई मेरी मदद कर सकता है।


आपके प्रश्न के सभी उत्तर अब तक आपके सर्वर कोड को फिर से लिखने का एक तरीका बताते हैं जिससे आप ajax काम करेंगे। उनमें से कोई भी बाईपास के बारे में नहीं है, जैसा कि आपने अपने प्रश्न में विशेष रूप से पूछा था। क्या आपको वास्तव में इस हेडर को बाईपास करने के लिए मिला? मुझे वास्तव में संदेह है कि एक होगा।
मोरादनेजाद

इसे बायपास करने का कोई तरीका नहीं है। लेकिन आप अपने बैकएंड पर एक फ़ाइल डाल सकते हैं जो अनुरोध करता है। तो आप अपने स्वयं के सर्वर पर फ़ाइल को अजाक्स कहते हैं, वह फ़ाइल पुनर्प्राप्त से डेटा लोड करती है। पीएचपी और उन्हें अपनी जावास्क्रिप्ट पर वापस भेजती है। उस स्थिति में कोई कोर नियम आपको रोक नहीं रहे हैं।
जोना पॉलस

जवाबों:


367

इसे पुनः प्राप्त करने के शीर्ष पर रखें।

header('Access-Control-Allow-Origin: *');  

ध्यान दें कि यह प्रभावी रूप से CORS सुरक्षा को अक्षम करता है, और आपके उपयोगकर्ताओं को हमले के लिए उजागर करता है। यदि आप पूरी तरह से निश्चित नहीं हैं कि आपको सभी मूलों को अनुमति देने की आवश्यकता है , तो आपको इसे और अधिक विशिष्ट मूल पर लॉक करना चाहिए:

header('Access-Control-Allow-Origin: https://www.example.com')

कृपया बेहतर समझ के लिए निम्नलिखित स्टैक उत्तर का संदर्भ लें Access-Control-Allow-Origin

https://stackoverflow.com/a/10636765/413670


54
बल्कि असुरक्षित है। नीचे मेरे जवाब की जाँच करें।
रोब

3
tnx, लेकिन आपको अपनी टिप्पणी में @RobQuist द्वारा बताए गए सभी मूलों तक पहुंच की अनुमति नहीं देनी चाहिए, और उनके जवाब में एक बेहतर दृष्टिकोण प्रदान किया
Rafay

2
इसलिए मुझे यह पृष्ठ मिला क्योंकि मुझे सर्वर पर वास्तव में 'बायपास' एक्सेस कंट्रोल की आवश्यकता थी। यहाँ समाधान कुछ भी दरकिनार नहीं है, लेकिन बस अपने स्वयं के सर्वर पर एक्सेस कंट्रोल को ठीक से कॉन्फ़िगर कर रहा है। मामले में किसी को भी वास्तव में यह बायपास करने की जरूरत है कि वे PHP के file_get_contents ($ Remote_url) का उपयोग कर सकते हैं ।. स्पष्ट रूप से ऐसा करने के कई तरीके हैं लेकिन यह है कि मैंने ऐसा कैसे किया।
शॉन व्हेनरी

1
@ शाश्विनहेरी जो मूल रूप से "प्रॉक्सिंग" का कार्य है। अच्छा समाधान यदि आप वास्तव में किसी अन्य वेबसाइट से डेटा को गतिशील रूप से लोड करना चाहते हैं जिसका आपके पास कोई नियंत्रण नहीं है।
रोब

1
डॉट स्क्रिप्ट कोर से PHP स्क्रिप्ट को चलाना चाहता था - मेरे दूसरे URL पर php स्क्रिप्ट ले जाया गया लेकिन क्रॉस-साइट स्क्रिप्टिंग त्रुटि हो रही थी। आपके द्वारा PHP के ऊपर दिखाए गए कोड को जोड़ा और पूरी तरह से काम किया। धन्यवाद!
राडदेवस

291

ठीक है, लेकिन आप सभी जानते हैं कि * एक वाइल्डकार्ड है और हर डोमेन से क्रॉस साइट स्क्रिप्टिंग की अनुमति देता है?

आप Access-Control-Allow-Originहर साइट के लिए एक से अधिक हेडर भेजना चाहेंगे - लेकिन दुर्भाग्यवश इसके आधिकारिक तौर पर कई Access-Control-Allow-Originहेडर भेजने के लिए , या कई मूल में डालने के लिए समर्थित नहीं है ।

यदि आप इसकी अनुमति देते हैं, तो आप मूल की जाँच करके और शीर्ष लेख को वापस भेज सकते हैं, यदि इसकी अनुमति है:

$origin = $_SERVER['HTTP_ORIGIN'];
$allowed_domains = [
    'http://mysite1.com',
    'https://www.mysite2.com',
    'http://www.mysite2.com',
];

if (in_array($origin, $allowed_domains)) {
    header('Access-Control-Allow-Origin: ' . $origin);
}

यह बहुत सुरक्षित है। आप मिलान को संपादित करना चाहते हैं और इसे कुछ regex या कुछ इस तरह से मैन्युअल फ़ंक्शन में बदल सकते हैं। कम से कम यह केवल 1 हेडर वापस भेजेगा, और आपको यह सुनिश्चित हो जाएगा कि अनुरोध कहां से आया है। कृपया ध्यान दें कि सभी HTTP हेडर को स्पूफ किया जा सकता है, लेकिन यह हेडर क्लाइंट की सुरक्षा के लिए है। उन मूल्यों के साथ अपने स्वयं के डेटा की रक्षा न करें। यदि आप अधिक जानना चाहते हैं, तो CORS और CSRF पर थोड़ा पढ़ें।

क्यों सुरक्षित है?

अन्य स्थानों से पहुंच की अनुमति देने के बाद आपकी खुद की विश्वसनीय साइट सत्र के उच्चीकरण की अनुमति देती है। मैं एक छोटे से उदाहरण के साथ जा रहा हूं - छवि फेसबुक एक वाइल्डकार्ड मूल की अनुमति देता है - इसका मतलब है कि आप अपनी खुद की वेबसाइट को कहीं भी बना सकते हैं, और इसे फेसबुक पर AJAX कॉल (या खुले iframes) कर सकते हैं। इसका मतलब है कि आप अपनी वेबसाइट के आगंतुक के फेसबुक की जानकारी में लॉग इन कर सकते हैं। इससे भी बदतर - आप POSTअनुरोधों को स्क्रिप्ट कर सकते हैं और किसी के फेसबुक पर डेटा पोस्ट कर सकते हैं - बस जब वे आपकी वेबसाइट ब्राउज़ कर रहे हों।

ACAOहेडर का उपयोग करते समय बहुत सतर्क रहें !


12
मुझे लगता है कि आपको सूची में प्रत्येक आइटम के सामने http: // डालने की आवश्यकता है। कम से कम मैंने एक साइट के लिए किया था जिस पर मैं काम कर रहा था।
ब्लाक 3

2
अफसोस की बात है, यह काम नहीं कर रहा है। मेरा मानना ​​है कि हेडर को प्रति कॉल केवल एक अपवाद प्रदान किया जा सकता है ()।
लूसीड

5
@Shanimal & lewsid -> मुझे लगता है कि अल्पविराम से अलग वास्तव में काम नहीं करता है। संदर्भ: w3.org/TR/cors
Rob

3
डोमेन की सूची से निपटने के लिए, यहां एक प्रासंगिक उत्तर दें: stackoverflow.com/a/1850482/766177
वैलेंटाइन डेस्पा

13
यह इस तरह से 4 हेडर जोड़ना व्यर्थ है क्योंकि प्रत्येक कॉल header()उसी प्रकार के पिछले हेडर को बदलने के लिए है। तो वास्तव में आप जो कुछ भी कर रहे हैं वह आखिरी हैडर सेट कर रहा है। मैनुअल प्रविष्टि में कहा गया है की आप एक दूसरा पैरामीटर सेट कर सकते हैं कि falseपिछले हैडर ओवरराइट किया जा रहा रोकने के लिए।
बैडहोरसी

31

चेतावनी , क्रोम (और अन्य ब्राउज़र) शिकायत करेंगे कि यदि आप कुछ अन्य उत्तरों का पालन करते हैं तो कई ACAO हेडर सेट किए जाते हैं।

त्रुटि कुछ इस तरह होगी XMLHttpRequest cannot load ____. The 'Access-Control-Allow-Origin' header contains multiple values '____, ____, ____', but only one is allowed. Origin '____' is therefore not allowed access.

इसे इस्तेमाल करे:

$http_origin = $_SERVER['HTTP_ORIGIN'];

$allowed_domains = array(
  'http://domain1.com',
  'http://domain2.com',
);

if (in_array($http_origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_origin");
}

6
यह एक और भी बेहतर उपाय है जिसे मैंने पोस्ट किया है।
रॉब

7

MVC3 नियंत्रक को कॉल करते समय मैंने इस समस्या को ठीक किया है। मैंने कहा:

Response.AddHeader("Access-Control-Allow-Origin", "*"); 

मेरे पहले

return Json(model, JsonRequestBehavior.AllowGet);

और मुझे यह भी $.ajaxशिकायत थी कि यह मेरे अजाक्स कॉल में सामग्री-प्रकार के हेडर को स्वीकार नहीं करता है , इसलिए मैंने इसे टिप्पणी की क्योंकि मुझे पता है कि इसका JSON एक्शन को पारित किया जा रहा है।

उम्मीद है की वो मदद करदे।


2

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

class CorsAccessControl
{
    private $allowed = array();

    /**
     * Always adds your own domain with the current ssl settings.
     */
    public function __construct()
    {
        // Add your own domain, with respect to the current SSL settings.
        $this->allowed[] = 'http'
            . ( ( array_key_exists( 'HTTPS', $_SERVER )
                && $_SERVER['HTTPS'] 
                && strtolower( $_SERVER['HTTPS'] ) !== 'off' ) 
                    ? 's' 
                    : null )
            . '://' . $_SERVER['HTTP_HOST'];
    }

    /**
     * Optionally add additional domains. Each is only added one time.
     */
    public function add($domain)
    {
        if ( !in_array( $domain, $this->allowed )
        {
            $this->allowed[] = $domain;
        }
    /**
     * Send 'em all as one header so no browsers grumble about it.
     */
    public function send()
    {
        $domains = implode( ', ', $this->allowed );
        header( 'Access-Control-Allow-Origin: ' . $domains, true ); // We want to send them all as one shot, so replace should be true here.
    }
}

उपयोग:

$cors = new CorsAccessControl();

// If you are only authorizing your own domain:
$cors->send();

// If you are authorizing multiple domains:
foreach ($domains as $domain)
{
    $cors->add($domain);
}
$cors->send();

तुम्हें नया तरीका मिल गया है।


1

क्या आपने वास्तव में एक्सेस-कंट्रोल-अलाउंस-हेडर को अपने सर्वर से भेजे गए रिस्पॉन्स में जोड़ने की कोशिश की है? पसंद है Access-Control-Allow-Origin: *?


1
यह एक HTTP हेडर है जिसे आपका सर्वर ब्राउज़र को सूचित करने के लिए भेजता है कि इस तथ्य के बावजूद कॉलिंग स्क्रिप्ट के परिणाम को प्रकट करना ठीक है कि स्क्रिप्ट का मूल डोमेन सर्वर के डोमेन से मेल नहीं खाता है। क्रॉस-ओरिजिनल रिसोर्स शेयरिंग पर पढ़ें !
डैनियल ब्रोकमैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.