मुझे GET अनुरोध के बजाय एक विकल्प अनुरोध क्यों मिल रहा है?


288
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js" type="text/javascript"></script>
<script>
$.get("http://example.com/", function(data) {
     alert(data);
});
</script>

यह उस URL के लिए एक विकल्प का अनुरोध करता है, और फिर कॉलबैक को कभी भी कुछ भी नहीं कहा जाता है।

जब यह क्रॉस डोमेन नहीं होता है, तो यह ठीक काम करता है।

JQuery को केवल एक <script>नोड के साथ कॉल नहीं करना चाहिए और फिर लोड होने पर कॉलबैक करना चाहिए? मैं समझता हूं कि मैं परिणाम प्राप्त नहीं कर पाऊंगा (चूंकि यह क्रॉस डोमेन है), लेकिन यह ठीक है; मैं सिर्फ कॉल के माध्यम से जाना चाहता हूँ। यह एक बग है, या मैं कुछ गलत कर रहा हूं?


2
क्रॉस डोमेन का कॉस हो सकता है। उदाहरण के लिए, यदि आप अपनी फ़ाइल में हैं तो फ़ाइल: // PATH_TO_WEBSITE लोकलहोस्ट / WEBSITE_LINK का उपयोग करने के बजाय
James111

जवाबों:


262

एमडीएन के अनुसार ,

पूर्वनिर्धारित अनुरोध

सरल अनुरोधों (ऊपर चर्चा की गई) के विपरीत, "पहले से बताए गए अनुरोध" पहले HTTP विकल्प भेजने का अनुरोध करते हैं, दूसरे डोमेन पर संसाधन के लिए हैडर, यह निर्धारित करने के लिए कि क्या वास्तविक अनुरोध भेजने के लिए सुरक्षित है। क्रॉस-साइट अनुरोध इस तरह से पूर्वनिर्मित हैं क्योंकि उनके उपयोगकर्ता डेटा के लिए निहितार्थ हो सकते हैं। विशेष रूप से, एक अनुरोध पूर्वनिर्धारित है यदि:

  • यह GET या POST के अलावा अन्य तरीकों का उपयोग करता है। इसके अलावा, अगर POST का उपयोग एप्लिकेशन / x-www-form-urlencoded, मल्टीपार्ट / फॉर्म-डेटा या टेक्स्ट / प्लेन के अलावा अन्य सामग्री-प्रकार के साथ अनुरोध डेटा भेजने के लिए किया जाता है, जैसे कि यदि POST अनुरोध सर्वर पर XML पेलोड भेजता है आवेदन / xml या पाठ / xml का उपयोग कर, तो अनुरोध पूर्वनिर्मित है।
  • यह अनुरोध में कस्टम हेडर सेट करता है (जैसे अनुरोध एक्स-पिंगोथ्रर जैसे हेडर का उपयोग करता है)

43
इसने हमारी समस्या को निर्धारित किया, "एप्लिकेशन / जोंस" से "टेक्स्ट / प्लेन" में बदलते हुए भयानक विकल्प अनुरोध को रोक दिया
कीनो

10
मुझे समझ में नहीं आ रहा है कि ब्राउज़र केवल विकल्प भेजने का अनुरोध क्यों कर रहा है ताकि वास्तविक अनुरोध भेजा जा सके। लेकिन किस अर्थ में? मेरा मतलब है कि सर्वर कुछ प्रतिक्रिया हेडर के साथ प्रतिबंध भी लगा सकता है इसलिए इसकी आवश्यकता क्यों है?
हार्डिक

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

6
@davidnknight अगर सर्वर पर आपका डेटा भेजना खतरनाक हो सकता है, तो इसका मतलब है कि सर्वर से छेड़छाड़ हो सकती है, तो निश्चित रूप से दुर्भावनापूर्ण सर्वर आपके विकल्प के साथ "ज़रूर, भेजना!" वह सुरक्षा कैसी है? (ईमानदार सवाल)
मैट

3
"प्रीफ़्लाइट अनुरोध कोई सुरक्षा चीज़ नहीं है। बल्कि, वे नियम बदलने वाली चीज़ नहीं हैं।" -
प्रीफलाइट


9

यदि आप पीओ.एस.टी.

JSON.stringifyअपने फ़ॉर्म डेटा को सुनिश्चित करें और जैसे भेजें text/plain

<form id="my-form" onSubmit="return postMyFormData();">
    <input type="text" name="name" placeholder="Your Name" required>
    <input type="email" name="email" placeholder="Your Email" required>
    <input type="submit" value="Submit My Form">
</form>

function postMyFormData() {

    var formData = $('#my-form').serializeArray();
    formData = formData.reduce(function(obj, item) {
        obj[item.name] = item.value;
        return obj;
    }, {});
    formData = JSON.stringify(formData);

    $.ajax({
        type: "POST",
        url: "https://website.com/path",
        data: formData,
        success: function() { ... },
        dataType: "text",
        contentType : "text/plain"
    });
}

2

मुझे विश्वास नहीं है कि jQuery उस तरह से URL दिए जाने पर स्वाभाविक रूप से JSONP अनुरोध करेगा। हालाँकि, जब आप कॉलबैक के लिए क्या तर्क देते हैं, यह बताने के लिए JSONP अनुरोध करें:

$.get("http://metaward.com/import/http://metaward.com/u/ptarjan?jsoncallback=?", function(data) {
     alert(data);
});

यह पूरी तरह से उस तर्क का उपयोग करने के लिए स्क्रिप्ट प्राप्त करने के लिए है (जिसे "jsoncallback" नहीं कहा जाता है), इसलिए इस मामले में फ़ंक्शन को कभी भी नहीं बुलाया जाएगा। लेकिन, चूंकि आपने कहा था कि आप बस चाहते हैं कि metaward.com पर स्क्रिप्ट निष्पादित हो, जो इसे बनाएगी।


क्या मेरा कॉलबैक अभी भी अधिसूचित किया जाएगा कि स्क्रिप्ट तत्व पूरी तरह से लोड हो गया है? मैं सिर्फ यह सुनिश्चित करना चाहता हूं कि इसके लिए एपीआई की क्वेरी करने से पहले अपडेट हो जाए।
पॉल टारजन

यदि आप प्राप्त स्क्रिप्ट JSONP का समर्थन करते हैं, और आपके द्वारा पहचाने गए फ़ंक्शन को कॉल करने के लिए तैयार हैं। यदि स्क्रिप्ट कुछ नहीं करती है लेकिन JSON डेटा का कोई अन्य व्यवहार नहीं है, तो आप यह नहीं बता पाएंगे कि यह कब लोड किया गया है। यदि यह बताना आवश्यक है कि लोडिंग कब की गई है, तो आप अपने स्वयं के सर्वर पर एक स्क्रिप्ट लागू करने पर विचार कर सकते हैं जो प्रॉक्सी के रूप में कार्य करता है।
वोटडेयिसिपल

1

वास्तव में, सुरक्षा कारणों की वजह से क्रॉस-डोमेन AJAX (XMLHttp) अनुरोधों की अनुमति नहीं है (क्लाइंट-साइड से "प्रतिबंधित" वेबपृष्ठ लाने और इसे सर्वर पर वापस भेजने के बारे में सोचें - यह एक सुरक्षा मुद्दा होगा)।

एकमात्र समाधान कॉलबैक हैं। यह है: एक नई स्क्रिप्ट ऑब्जेक्ट बनाना और अंत-साइड जावास्क्रिप्ट के लिए src को इंगित करना, जो JSON मानों (myFunction ({data}) के साथ कॉलबैक है, myFunction एक फ़ंक्शन है जो डेटा के साथ कुछ करता है (उदाहरण के लिए, इसे संग्रहीत करना) एक चर म)।


1
सही है, लेकिन मैं इसे एक <script src = ""> या <img src = ""> में लोड कर सकता हूं और ब्राउज़र खुशी से इसे हिट करेगा। मैं सिर्फ यह जानना चाहता हूं कि जब यह पूरी तरह से लोड हो जाए तो मैं आयात के परिणाम के लिए क्वेरी कर सकता हूं।
पॉल टारजन

1

बस "एप्लिकेशन / जसन" को "टेक्स्ट / प्लेन" में बदलें और JSON.stringify (अनुरोध) को न भूलें:

var request = {Company: sapws.dbName, UserName: username, Password: userpass};
    console.log(request);
    $.ajax({
        type: "POST",
        url: this.wsUrl + "/Login",
        contentType: "text/plain",
        data: JSON.stringify(request),

        crossDomain: true,
    });

1

मुझे भी यही समस्या थी। मेरा फिक्स मेरी PHP स्क्रिप्ट में हेडर जोड़ना था जो केवल देव वातावरण में मौजूद हैं।

यह क्रॉस-डोमेन अनुरोधों की अनुमति देता है:

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

यह प्रीफ़लाइट अनुरोध को बताता है कि क्लाइंट के लिए यह ठीक है कि वह जो भी हेडर भेजना चाहता है:

header("Access-Control-Allow-Headers: *");

इस तरह अनुरोध को संशोधित करने की कोई आवश्यकता नहीं है।

यदि आपके पास अपने देव डेटाबेस में संवेदनशील डेटा है जो संभवतः लीक हो सकता है, तो आप इस बारे में दो बार सोच सकते हैं।


1

मेरे मामले में, मैं एक ही वेब सर्वर के लिए एक jQuery पोस्ट जारी कर रहा था के बाद से इस मुद्दे को CorS के लिए असंबंधित किया गया था। डेटा JSON था, लेकिन मैंने डेटा टाइप छोड़ दिया था: 'json' पैरामीटर।

जैसा कि डेविड लोप्स के उत्तर में दिखाया गया है, मेरे पास कोई कंटेंट टाइप नहीं था (न ही मैंने जोड़ा था)।


0

यह फ़ायरफ़ॉक्स और ओपेरा की तरह दिख रहा है (मैक पर परीक्षण किया गया है) इस तरह के क्रॉस डोमेन को पसंद नहीं करता है (लेकिन सफारी इसके साथ ठीक है)।

आपको दूरस्थ पृष्ठ को कर्ल करने के लिए एक स्थानीय सर्वर साइड कोड को कॉल करना पड़ सकता है।


0

मैं निम्नलिखित हेडर की मदद से इसे ठीक करने में सक्षम था

Access-Control-Allow-Origin
Access-Control-Allow-Headers
Access-Control-Allow-Credentials
Access-Control-Allow-Methods

यदि आप Nodejs पर हैं, तो यहां वह कोड है जिसे आप कॉपी / पेस्ट कर सकते हैं।

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin','*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH');
  next();
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.