क्रॉस-ऑरिजनल रिसोर्स शेयरिंग (कोर) पोस्ट अनुरोध कैसे प्राप्त करें


216

मेरे पास मेरे स्थानीय लैन (मशीन) पर एक मशीन है जिसमें दो वेब सर्वर हैं। पहला XBMC (पोर्ट 8080 पर) में इन-बिल्ट इन है और हमारी लाइब्रेरी को प्रदर्शित करता है। दूसरा सर्वर एक चेरी पाइथन स्क्रिप्ट (पोर्ट 8081) है जिसका उपयोग मैं मांग पर एक फ़ाइल रूपांतरण को ट्रिगर करने के लिए कर रहा हूं। फ़ाइल रूपांतरण XBMC सर्वर से दिए गए पृष्ठ से AJAX POST अनुरोध द्वारा ट्रिगर किया गया है।

  • गोटो http: // machineA: 8080 जो पुस्तकालय प्रदर्शित करता है
  • लाइब्रेरी प्रदर्शित है
  • 'कन्वर्ट' लिंक पर उपयोगकर्ता क्लिक जो निम्नलिखित आदेश जारी करता है -

jQuery के अजाक्स अनुरोध

$.post('http://machineA:8081', {file_url: 'asfd'}, function(d){console.log(d)})
  • ब्राउज़र निम्नलिखित हेडर के साथ एक HTTP विकल्प अनुरोध जारी करता है;

अनुरोध हैडर - विकल्प

Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: http://machineA:8080
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-requested-with
  • सर्वर निम्नलिखित के साथ प्रतिक्रिया करता है;

प्रतिक्रिया हैडर - विकल्प (स्थिति = 200 ठीक)

Content-Length: 0
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:40:29 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: text/html;charset=ISO-8859-1
  • तब बातचीत बंद हो जाती है। ब्राउज़र, सिद्धांत रूप में, एक POST अनुरोध जारी करना चाहिए, क्योंकि सर्वर ने सही (?) CORS हेडर (एक्सेस-कंट्रोल-अलाउंस-ओरिजिन: *) के साथ जवाब दिया।

समस्या निवारण के लिए, मैंने http://jquery.com से समान $ .post कमांड भी जारी किया है । यह वह जगह है जहाँ मैं stumped हूँ, jquery.com से, पोस्ट अनुरोध काम करता है, एक पोस्ट के बाद एक विकल्प अनुरोध भेजा जाता है। इस लेनदेन के हेडर नीचे हैं;

अनुरोध हैडर - विकल्प

Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: http://jquery.com
Access-Control-Request-Method: POST

प्रतिक्रिया हैडर - विकल्प (स्थिति = 200 ठीक)

Content-Length: 0
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:37:59 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: text/html;charset=ISO-8859-1

अनुरोध हैडर - POST

Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://jquery.com/
Content-Length: 12
Origin: http://jquery.com
Pragma: no-cache
Cache-Control: no-cache

प्रतिक्रिया हैडर - पोस्ट (स्टेटस = 200 ओके)

Content-Length: 32
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:37:59 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: application/json

मैं बाहर काम नहीं कर सकता क्यों एक ही अनुरोध एक साइट से काम करेगा, लेकिन दूसरे से नहीं। मैं उम्मीद कर रहा हूं कि कोई मुझे याद दिलाने में सक्षम हो सकता है। आपकी सहायताके लिए धन्यवाद!


यदि दोनों वेब सर्वर एक ही मशीन पर हैं तो क्या CORS की आवश्यकता है?
jdigital

8
मेरे ज्ञान के सर्वश्रेष्ठ के लिए यह अलग बंदरगाह की वजह से एक कोर अनुरोध है। इसके अलावा, विकल्प अनुरोध इंगित करता है कि ब्राउज़र इसे एक कोर अनुरोध के रूप में मान रहा है
जेम्स

जवाबों:


157

मैं अंत में इस लिंक पर ठोकर खाई " एक कोर पोस्ट अनुरोध सादे जावास्क्रिप्ट से काम करता है, लेकिन jQuery के साथ क्यों नहीं? "

 Access-Control-Request-Headers: x-requested-with

सभी कोर अनुरोधों के लिए हेडर। jQuery 1.5.2 ऐसा नहीं करता है। इसके अलावा, एक ही सवाल के अनुसार, एक सर्वर प्रतिक्रिया हेडर की स्थापना

Access-Control-Allow-Headers: *

प्रतिक्रिया जारी रखने की अनुमति नहीं देता है। आपको प्रतिक्रिया हेडर को विशेष रूप से आवश्यक हेडर शामिल करना सुनिश्चित करना होगा। अर्थात:

Access-Control-Allow-Headers: x-requested-with 

70

निवेदन:

 $.ajax({
            url: "http://localhost:8079/students/add/",
            type: "POST",
            crossDomain: true,
            data: JSON.stringify(somejson),
            dataType: "json",
            success: function (response) {
                var resp = JSON.parse(response)
                alert(resp.status);
            },
            error: function (xhr, status) {
                alert("error");
            }
        });

प्रतिक्रिया:

response = HttpResponse(json.dumps('{"status" : "success"}'))
response.__setitem__("Content-type", "application/json")
response.__setitem__("Access-Control-Allow-Origin", "*")

return response

3
यदि सर्वर क्रॉस ओरिजिन को स्वीकार नहीं करता है, तो क्रॉसडोमेन = ट्रू को समस्या को हल करने की आवश्यकता नहीं है। dataType का उपयोग करना: "jsonp" और कॉलबैक को jsonpCallback की तरह सेट करना: "प्रतिक्रिया" ऐसा करने के लिए बेहतर विचार होगा। इन्हें भी देखें: api.jquery.com/jquery.ajax
BonifatiusK

14

मैंने Jquery ajax के साथ अपने अनुरोध हेडर को सेट करके Google डिस्टेंस मैट्रिक्स एपीआई का उपयोग करते समय अपनी समस्या का हल किया। नीचे देखो।

var settings = {
          'cache': false,
          'dataType': "jsonp",
          "async": true,
          "crossDomain": true,
          "url": "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=place_id:"+me.originPlaceId+"&destinations=place_id:"+me.destinationPlaceId+"&region=ng&units=metric&key=mykey",
          "method": "GET",
          "headers": {
              "accept": "application/json",
              "Access-Control-Allow-Origin":"*"
          }
      }

      $.ajax(settings).done(function (response) {
          console.log(response);

      });

नोट करें कि मैंने सेटिंग्स में क्या जोड़ा
**

"headers": {
          "accept": "application/json",
          "Access-Control-Allow-Origin":"*"
      }

**
मुझे आशा है कि यह मदद करता है।


यह एकमात्र समाधान है जो सर्वर-साइड पर कुछ भी बदले बिना हमारे लिए काम करता है ... थैंक्स चमत्कार
टिमस्टा

1
@ टिम्स्टा, मुझे खुशी है कि मेरे सुझाव ने आपके लिए काम किया। अतिप्रवाह को ढेर करने के लिए आभारी। आपका दिन अच्छा रहे।
मिराकल जूल

13

हल खोजने के लिए मुझे कुछ समय दिया।

मामले में अपने सर्वर प्रतिक्रिया सही ढंग से और अनुरोध बात नहीं, आप जोड़ना चाहिए है withCredentials: trueकरने के लिए xhrFieldsअनुरोध में:

$.ajax({
    url: url,
    type: method,
    // This is the important part
    xhrFields: {
        withCredentials: true
    },
    // This is the important part
    data: data,
    success: function (response) {
        // handle the response
    },
    error: function (xhr, status) {
        // handle errors
    }
});

नोट: jQuery> = 1.5.1 आवश्यक है


jquery संस्करण ठीक है? क्या आपने सेट किया था withCredentials: true? आप सुनिश्चित करें कि आपके पास प्रासंगिक हेडर हैं?
Dekel

हां, 1withCredential: सच्चा , jquery संस्करण: 3.2.1`। वास्तव में यह डाकिया के माध्यम से काम कर रहा है, लेकिन इसके क्रोम ब्राउजर से नहीं गुजर रहा है
मोक्स शाह

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

क्या आप मुझे बता सकते हैं कि सर्वर पर रिस्पांस हेडर की क्या आवश्यकता है?
मोक्स शाह

@ MoxShah यह एक पूरी तरह से अलग सवाल है और वहाँ संसाधनों का एक बहुत कुछ कर रहे हैं :)
Dekel

9

खैर मैं कुछ हफ़्ते के लिए इस मुद्दे से जूझता रहा।

ऐसा करने के लिए सबसे आसान, सबसे आज्ञाकारी और गैर हैक करने का तरीका संभवतः एक प्रदाता जावास्क्रिप्ट एपीआई का उपयोग करना है जो ब्राउज़र आधारित कॉल नहीं करता है और क्रॉस मूल अनुरोधों को संभाल सकता है।

उदाहरण के लिए फेसबुक जावास्क्रिप्ट एपीआई और गूगल जेएस एपीआई।

यदि आपका एपीआई प्रदाता चालू नहीं है और अपनी प्रतिक्रिया में क्रॉस ओरिजनल रिसोर्स ओरिजिन '*' हेडर का समर्थन नहीं करता है और इसमें जेएस आपी नहीं है (हां मैं आपके बारे में याहू की बात कर रहा हूं), तो आप तीन विकल्पों में से एक से टकराए हैं-

  1. आपके अनुरोधों में jsonp का उपयोग करना जो आपके URL में एक कॉलबैक फ़ंक्शन जोड़ता है जहां आप अपनी प्रतिक्रिया को संभाल सकते हैं। ऐसा करने से अनुरोध URL बदल जाएगा, इसलिए URL के अंत में आपके API सर्वर को कॉलबैक = संभालने के लिए सुसज्जित होना चाहिए।

  2. अपने एपीआई सर्वर के लिए अनुरोध भेजें जो आपके द्वारा नियंत्रक है और ग्राहक के रूप में या तो उसी डोमेन में है या उसके पास क्रॉस ओरिजिनल रिसोर्स शेयरिंग सक्षम है जहां से आप 3 डी एपीआई एपीआई सर्वर के लिए अनुरोध को प्रॉक्सी कर सकते हैं।

  3. संभवतः उन मामलों में सबसे उपयोगी है जहां आप OAuth अनुरोध कर रहे हैं और उपयोगकर्ता इंटरैक्शन को संभालने की आवश्यकता है Haha! window.open('url',"newwindowname",'_blank', 'toolbar=0,location=0,menubar=0')


4

लारवेल के संयोजन में इसका उपयोग करने से मेरी समस्या हल हो गई। इस हेडर को अपने jquery रिक्वेस्ट में जोड़ें Access-Control-Request-Headers: x-requested-withऔर सुनिश्चित करें कि आपके सर्वर साइड रिस्पांस में यह हेडर सेट है Access-Control-Allow-Headers: *


6
मैन्युअल रूप से अनुरोध में कॉर्स हेडर जोड़ने का कोई कारण नहीं है। ब्राउज़र हमेशा आपके लिए अनुरोध के लिए प्रोप कॉर्स हेडर जोड़ देगा।
रे निकोलस

1
असली चुनौती सर्वर को सही Access-Control-Allow-Headersऔर JQ की आपूर्ति सही करने के साथ जवाब देने के लिए मिल रही है Access-Control-Request-Headers(प्लस आप कोड के माध्यम से जोड़ते हैं) जिनमें से कोई भी वाइल्डकार्ड नहीं हो सकता है। यह पूर्व-उड़ान को उड़ाने के लिए केवल एक "खराब" हेडर लेता है, जैसे If-None-Matchकि सशर्त जीईटी के लिए उपयोग करना, अगर सर्वर में यह सूचीबद्ध नहीं है।
llc

1

किसी कारण से, GET अनुरोधों के बारे में एक प्रश्न इस एक के साथ विलय कर दिया गया था, इसलिए मैं इसका जवाब यहां दूंगा।

यह साधारण फ़ंक्शन असंगत रूप से एक कोरस-सक्षम पृष्ठ से HTTP स्थिति उत्तर प्राप्त करेगा। यदि आप इसे चलाते हैं, तो आप देखेंगे कि XMLHttpRequest के माध्यम से एक्सेस किए जाने पर उचित हेडर वाला केवल एक पेज 200 स्थिति देता है - चाहे GET या POST का उपयोग किया गया हो। क्लाइंट साइड पर कुछ भी नहीं किया जा सकता है इसके अलावा इसे पाने के लिए संभवतः JSONP का उपयोग करें यदि आपको बस एक json ऑब्जेक्ट की आवश्यकता है।

निम्नलिखित को आसानी से xmlHttpRequestObject ऑब्जेक्ट में रखे गए डेटा को प्राप्त करने के लिए संशोधित किया जा सकता है:

function checkCorsSource(source) {
  var xmlHttpRequestObject;
  if (window.XMLHttpRequest) {
    xmlHttpRequestObject = new XMLHttpRequest();
    if (xmlHttpRequestObject != null) {
      var sUrl = "";
      if (source == "google") {
        var sUrl = "https://www.google.com";
      } else {
        var sUrl = "https://httpbin.org/get";
      }
      document.getElementById("txt1").innerHTML = "Request Sent...";
      xmlHttpRequestObject.open("GET", sUrl, true);
      xmlHttpRequestObject.onreadystatechange = function() {
        if (xmlHttpRequestObject.readyState == 4 && xmlHttpRequestObject.status == 200) {
          document.getElementById("txt1").innerHTML = "200 Response received!";
        } else {
          document.getElementById("txt1").innerHTML = "200 Response failed!";
        }
      }
      xmlHttpRequestObject.send();
    } else {
      window.alert("Error creating XmlHttpRequest object. Client is not CORS enabled");
    }
  }
}
<html>
<head>
  <title>Check if page is cors</title>
</head>
<body>
  <p>A CORS-enabled source has one of the following HTTP headers:</p>
  <ul>
    <li>Access-Control-Allow-Headers: *</li>
    <li>Access-Control-Allow-Headers: x-requested-with</li>
  </ul>
  <p>Click a button to see if the page allows CORS</p>
  <form name="form1" action="" method="get">
    <input type="button" name="btn1" value="Check Google Page" onClick="checkCorsSource('google')">
    <input type="button" name="btn1" value="Check Cors Page" onClick="checkCorsSource('cors')">
  </form>
  <p id="txt1" />
</body>
</html>


1

मेरे पास एक ही मुद्दा था जहां jquery ajax ने केवल मुझे पोस्ट अनुरोधों पर cors मुद्दे दिए, जहां अनुरोधों ने ठीक काम किया - मैंने बिना किसी परिणाम के साथ सब कुछ थक गया। मैं अपने सर्वर आदि में सही हेडर रखता था। jquery के बजाय XMLHTTPRequest का उपयोग करने के लिए बदलने से मेरा मुद्दा तुरंत ठीक हो गया। कोई फर्क नहीं पड़ता कि मैंने किस संस्करण का उपयोग किया था, इसे ठीक नहीं किया। अगर आपको पिछड़े ब्राउज़र संगतता की आवश्यकता नहीं है, तो फ़ेच भी समस्याओं के बिना काम करता है।

        var xhr = new XMLHttpRequest()
        xhr.open('POST', 'https://mywebsite.com', true)
        xhr.withCredentials = true
        xhr.onreadystatechange = function() {
          if (xhr.readyState === 2) {// do something}
        }
        xhr.setRequestHeader('Content-Type', 'application/json')
        xhr.send(json)

उम्मीद है कि यह किसी और ही मुद्दों के साथ मदद करता है।


1

यह मेरे लिए काम करने का एक सारांश है:

एक नया फ़ंक्शन परिभाषित करें ( $.ajaxसरलीकृत करने के लिए लपेटा गया):

jQuery.postCORS = function(url, data, func) {
  if(func == undefined) func = function(){};
  return $.ajax({
    type: 'POST', 
    url: url, 
    data: data, 
    dataType: 'json', 
    contentType: 'application/x-www-form-urlencoded', 
    xhrFields: { withCredentials: true }, 
    success: function(res) { func(res) }, 
    error: function() { 
            func({}) 
    }
  });
}

उपयोग:

$.postCORS("https://example.com/service.json",{ x : 1 },function(obj){
      if(obj.ok) {
           ...
      }
});

इसके अलावा के साथ काम करता .done, .fail, आदि:

$.postCORS("https://example.com/service.json",{ x : 1 }).done(function(obj){
      if(obj.ok) {
           ...
      }
}).fail(function(){
    alert("Error!");
});

सर्वर साइड (इस मामले में जहाँ example.com होस्ट है), इन हेडर को सेट करें (PHP में कुछ सैंपल कोड जोड़ा गया):

header('Access-Control-Allow-Origin: https://not-example.com');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 604800');
header("Content-type: application/json");
$array = array("ok" => $_POST["x"]);
echo json_encode($array);

यह एकमात्र तरीका है जो मैं जेएस से सही मायने में POST पार करने के लिए जानता हूं।

JSONP POST को GET में परिवर्तित करता है जो सर्वर लॉग में संवेदनशील जानकारी प्रदर्शित कर सकता है।


0

हेडर जोड़ने या नियंत्रण नीति सेट करने के दौरान कुछ कारणों से यदि आप अभी भी कहीं नहीं मिल रहे हैं, तो आप Apache ProxyPass का उपयोग करने पर विचार कर सकते हैं ...

उदाहरण के लिए एक <VirtualHost>एसएसएल का उपयोग करने वाले दो निर्देशों का पालन करते हैं:

SSLProxyEngine On
ProxyPass /oauth https://remote.tld/oauth

सुनिश्चित करें कि निम्नलिखित अपाचे मॉड्यूल लोड किए गए हैं (उन्हें a2enmod का उपयोग करके लोड करें):

  • प्रतिनिधि
  • proxy_connect
  • proxy_http

जाहिर है आप अपाचे प्रॉक्सी का उपयोग करने के लिए अपने AJAX अनुरोध यूआरएल को बदलना होगा ...


-3

पार्टी के लिए यह थोड़ी देर की बात है, लेकिन मैं कुछ दिनों से इससे जूझ रहा हूं। यह संभव है और मेरे द्वारा यहां दिए गए उत्तरों में से कोई भी काम नहीं किया है। यह भ्रामक सरल है। यहां .ajax कॉल करें:

    <!DOCTYPE HTML>
    <html>
    <head>
    <body>
     <title>Javascript Test</title>
     <script src="http://code.jquery.com/jquery-latest.min.js"></script>
     <script type="text/javascript">
     $(document).domain = 'XXX.com';
     $(document).ready(function () {
     $.ajax({
        xhrFields: {cors: false},
        type: "GET",
        url: "http://XXXX.com/test.php?email='steve@XXX.com'",
        success: function (data) {
           alert(data);
        },
        error: function (x, y, z) {
           alert(x.responseText + " :EEE: " + x.status);
        }
    });
    });
    </script> 
    </body>
    </html>

यहाँ सर्वर ओर php है:

    <html>
    <head>
     <title>PHP Test</title>
     </head>
    <body>
      <?php
      header('Origin: xxx.com');
      header('Access-Control-Allow-Origin:*');
      $servername = "sqlxxx";
      $username = "xxxx";
      $password = "sss";
      $conn = new mysqli($servername, $username, $password);
      if ($conn->connect_error) {
        die( "Connection failed: " . $conn->connect_error);
      }
      $sql = "SELECT email, status, userdata  FROM msi.usersLive";
      $result = $conn->query($sql);
      if ($result->num_rows > 0) {
      while($row = $result->fetch_assoc()) {
        echo $row["email"] . ":" . $row["status"] . ":" . $row["userdata"] .  "<br>";
      }
    } else {
      echo "{ }";
    }
    $conn->close();
    ?>
    </body>


1
इसके लायक क्या है, ओरिजिन हेडर एक रिक्वेस्ट हैडर है, न कि रिस्पॉन्स हेडर। आपकी php स्क्रिप्ट को इसे सेट नहीं करना चाहिए।
नूडल्स

Hmmph। इससे मेरी उम्मीद बढ़ गई और फिर उन्हें धराशायी कर दिया जब मैंने देखा कि आप अपने कोड में एक AJAX "GET" बना रहे हैं, जब ओपी ने स्पष्ट रूप से कहा कि वह "GET" का उपयोग करके AVOID की कोशिश कर रहा था और "POST" का उपयोग करना चाहता था।
स्टीव साउडर

कॉर्स हेडर्स क्रिया को शामिल किए बिना ही काम करते हैं। हम $.ajax()एक सही ढंग से कॉन्फ़िगर किए गए सर्वर के खिलाफ सभी क्रियाओं को लागू करने में सक्षम हैं । सबसे कठिन हिस्सा Access-Control-Request-Headersसही हो रहा है, लेकिन यह भी मुश्किल नहीं है। जैसा कि पिछले पोस्टरों ने उल्लेख किया है, यह वाइल्डकार्ड नहीं बल्कि हेडर का श्वेतसूची होना चाहिए।
llc
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.