लाने और मोड में पास करने की कोशिश: नो-कोर्स


166

मैं http://catfacts-api.appspot.com/api/facts?number=99पोस्टमैन के माध्यम से इस समापन बिंदु को हिट कर सकता हूं और यह वापस आ जाता हैJSON

इसके अतिरिक्त, मैं create-react-app का उपयोग कर रहा हूं और किसी भी सर्वर कॉन्फिगरेशन को स्थापित करने से बचना चाहूंगा।

अपने क्लाइंट कोड में मैं fetchएक ही काम करने के लिए उपयोग करने की कोशिश कर रहा हूं , लेकिन मुझे त्रुटि मिलती है:

अनुरोधित संसाधन पर कोई 'एक्सेस-कंट्रोल-अनुमति-उत्पत्ति' हेडर मौजूद नहीं है। उत्पत्ति ' http: // localhost: 3000 ' इसलिए पहुंच की अनुमति नहीं है। यदि कोई अपारदर्शी प्रतिक्रिया आपकी आवश्यकताओं को पूरा करती है, तो संसाधन को अक्षम करने के लिए 'नो-कॉर्स' के लिए अनुरोध के मोड को सेट करें।

तो मैं अपने Fetch को एक ऑब्जेक्ट में पास करने की कोशिश कर रहा हूं, जो कि CORS को अक्षम कर देगा, जैसे:

fetch('http://catfacts-api.appspot.com/api/facts?number=99', { mode: 'no-cors'})
  .then(blob => blob.json())
  .then(data => {
    console.table(data);
    return data;
  })
  .catch(e => {
    console.log(e);
    return e;
  });

दिलचस्प है कि मुझे जो त्रुटि मिली है वह वास्तव में इस फ़ंक्शन के साथ एक सिंटैक्स त्रुटि है। मुझे यकीन नहीं है कि मेरा वास्तविक fetchटूट गया है, क्योंकि जब मैं {मोड: 'नो-कॉर्स'} ऑब्जेक्ट को हटाता हूं, और इसे अलग URL के साथ आपूर्ति करता हूं तो यह ठीक काम करता है।

मैंने ऑब्जेक्ट में पास करने की भी कोशिश की है { mode: 'opaque'}, लेकिन यह ऊपर से मूल त्रुटि देता है।

मुझे विश्वास है कि मुझे जो कुछ भी करने की आवश्यकता है वह कोर को निष्क्रिय कर रहा है .. मुझे क्या याद आ रहा है?

जवाबों:


291

mode: 'no-cors'जादुई तरीके से काम नहीं करेंगे। वास्तव में यह चीजों को बदतर बनाता है, क्योंकि इसका एक प्रभाव ब्राउज़रों को बताने के लिए है, "सभी परिस्थितियों में प्रतिक्रिया शरीर और हेडर की सामग्री को देखने से मेरे सीमांत जावास्क्रिप्ट कोड को ब्लॉक करें।" बेशक आप लगभग ऐसा कभी नहीं चाहते हैं।

फ्रंटएंड जावास्क्रिप्ट से क्रॉस-ऑरिजिनल रिक्वेस्ट के साथ क्या होता है, रिसोर्स क्रॉस-ऑरिजिन एक्सेस करने से डिफ़ॉल्ट ब्लॉक फ्रंटेंड कोड के ब्राउजर। यदि Access-Control-Allow-Originप्रतिक्रिया में है, तो ब्राउज़र उस अवरुद्ध को आराम देगा और आपके कोड को प्रतिक्रिया तक पहुंचने की अनुमति देगा।

लेकिन यदि कोई साइट Access-Control-Allow-Originअपनी प्रतिक्रियाओं में नहीं भेजती है , तो आपका फ्रंटएंड कोड सीधे उस साइट से प्रतिक्रियाओं तक नहीं पहुंच सकता है। विशेष रूप से, आप इसे निर्दिष्ट करके ठीक नहीं कर सकते mode: 'no-cors'(वास्तव में यह सुनिश्चित करेंगे आपका फ्रंटएंड कोड प्रतिक्रिया सामग्री तक नहीं पहुंच सकता है)।

हालाँकि, एक चीज जो काम करेगी : यदि आप एक कॉर्स प्रॉक्सी के माध्यम से अपना अनुरोध भेजते हैं , तो इस तरह:

var proxyUrl = 'https://cors-anywhere.herokuapp.com/',
    targetUrl = 'http://catfacts-api.appspot.com/api/facts?number=99'
fetch(proxyUrl + targetUrl)
  .then(blob => blob.json())
  .then(data => {
    console.table(data);
    document.querySelector("pre").innerHTML = JSON.stringify(data, null, 2);
    return data;
  })
  .catch(e => {
    console.log(e);
    return e;
  });
<pre></pre>

नोट: यदि आप https://cors-anywhere.herokuapp.com का उपयोग करने का प्रयास करने जाते हैं, तो आप पाते हैं कि यह नीचे है , आप आसानी से हरोकू को आसानी से केवल 2-3 मिनट में 5 कमांडों के साथ अपनी तैनाती दे सकते हैं:

git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master

उन आदेशों को चलाने के बाद, आप अपने स्वयं के CORS कहीं भी सर्वर पर चल रहे हैं, जैसे, https://cryptic-headland-94862.herokuapp.com/ । तो फिर अपने अनुरोध URL को https://cors-anywhere.herokuapp.comउपसर्ग करने के बजाय, अपने स्वयं के उदाहरण के लिए URL के बजाय उपसर्ग करें; जैसे, https://cryptic-headland-94862.herokuapp.com/https://example.com


मैं http://catfacts-api.appspot.com/api/facts?number=99पोस्टमैन के माध्यम से इस समापन बिंदु को हिट कर सकता हूं

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS बताते हैं कि ऐसा क्यों है कि भले ही आप पोस्टमैन के साथ प्रतिक्रिया का उपयोग कर सकते हैं, ब्राउज़र आपको प्रतिक्रिया के साथ क्रॉस-ऑरिजनल का उपयोग करने की अनुमति नहीं देंगे। एक वेब ऐप में जावास्क्रिप्ट कोड चल रहा है जब तक कि प्रतिक्रिया में Access-Control-Allow-Originप्रतिक्रिया शीर्षलेख शामिल नहीं है।

http://catfacts-api.appspot.com/api/facts?number=99 का कोई Access-Control-Allow-Originप्रतिक्रिया शीर्षलेख नहीं है, इसलिए कोई तरीका नहीं है जिससे आपका फ्रंटएंड कोड प्रतिक्रिया क्रॉस-ऑरिजिन तक पहुँच सके।

आपके ब्राउज़र को प्रतिक्रिया ठीक मिल सकती है और आप इसे पोस्टमैन में देख सकते हैं और यहां तक ​​कि ब्राउज़र devtools में भी- लेकिन इसका मतलब यह नहीं है कि ब्राउज़र इसे आपके कोड में उजागर कर देंगे। वे नहीं करेंगे, क्योंकि इसका कोई Access-Control-Allow-Originप्रतिक्रिया शीर्षक नहीं है। इसलिए आपको इसे प्राप्त करने के लिए प्रॉक्सी का उपयोग करना चाहिए।

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


इसलिए मैं अपने Fetch को एक ऑब्जेक्ट में पास करने की कोशिश कर रहा हूं, जो कि CORS को निष्क्रिय कर देगा

आप ऐसा नहीं करना चाहते हैं। स्पष्ट होने के लिए, जब आप कहते हैं कि आप "CORS को अक्षम करना चाहते हैं" तो ऐसा लगता है कि आप वास्तव में उसी मूल नीति को निष्क्रिय करना चाहते हैं । CorS वास्तव में ऐसा करने का एक तरीका है - CORS समान-मूल नीति को ढीला करने का एक तरीका है, न कि इसे प्रतिबंधित करने का तरीका।

लेकिन वैसे भी, यह सच है - आप अपने स्थानीय वातावरण में - सुरक्षा को अक्षम करने और असुरक्षित रूप से चलाने के लिए अपने ब्राउज़र रनटाइम फ़्लैग जैसी चीजें कर सकते हैं, या समान-मूल नीति के आसपास पाने के लिए स्थानीय रूप से ब्राउज़र एक्सटेंशन स्थापित कर सकते हैं, लेकिन यह सब करता है केवल स्थानीय स्तर पर आपके लिए स्थिति बदल रहा है।

इससे कोई फर्क नहीं पड़ता कि आप स्थानीय रूप से क्या बदलते हैं, आपके ऐप का उपयोग करने का प्रयास करने वाला कोई अन्य व्यक्ति अभी भी उसी मूल नीति में चलने वाला है, और ऐसा कोई तरीका नहीं है जिससे आप अपने ऐप के अन्य उपयोगकर्ताओं के लिए उसे अक्षम कर सकें।

आप संभवतः mode: 'no-cors'कुछ सीमित मामलों को छोड़कर अभ्यास में कभी भी उपयोग नहीं करना चाहते हैं , और तब भी जब आप जानते हैं कि आप वास्तव में क्या कर रहे हैं और क्या प्रभाव हैं। ऐसा इसलिए है क्योंकि mode: 'no-cors'ब्राउज़र के लिए वास्तव में सेटिंग क्या कहती है, "सभी परिस्थितियों में प्रतिक्रिया बॉडी और हेडर की सामग्री को देखने से मेरे सीमांत जावास्क्रिप्ट कोड को ब्लॉक करें।" ज्यादातर मामलों में यह स्पष्ट रूप से नहीं है कि आप क्या चाहते हैं।


जहां तक ​​उन मामलों का जब आप उपयोग करने पर विचार करना चाहते हैं mode: 'no-cors', तो जवाब देखें कि अपारदर्शी प्रतिक्रियाओं पर क्या सीमाएं लागू होती हैं? विवरण के लिए। इसका सार यह है कि मामले हैं:

  • सीमित मामला है जब आप एक की सामग्री के एक और मूल से एक संसाधन बनाने के लिए JavaScript का उपयोग कर रहे में <script>, <link rel=stylesheet>, <img>, <video>, <audio>, <object>, <embed>, या <iframe>तत्व (जो संसाधनों की embedding क्योंकि काम करता है पार मूल के लोगों के लिए अनुमति दी है) - लेकिन किसी कारण से आप ऐसा नहीं करना चाहते हैं या नहीं कर सकते हैं केवल दस्तावेज़ के मार्कअप होने से तत्व के लिए संसाधन URL hrefया srcविशेषता के रूप में उपयोग करें ।

  • जब केवल एक चीज जिसे आप किसी संसाधन के साथ करना चाहते हैं, उसे कैश करना है। के रूप में जवाब में alluded क्या सीमाओं अपारदर्शी प्रतिक्रियाओं के लिए लागू होते हैं? उस स्थिति में, जब आप सेवा कार्यकर्ता का उपयोग कर रहे हैं, जिस स्थिति में एपीआई प्रासंगिक है, वह कैश संग्रहण एपीआई है

लेकिन उन सीमित मामलों में भी, जागरूक होने के लिए कुछ महत्वपूर्ण आधार हैं; जवाब देखें कि अपारदर्शी प्रतिक्रियाओं पर क्या सीमाएं लागू होती हैं? विवरण के लिए।


मैंने भी ऑब्जेक्ट में पास होने की कोशिश की है { mode: 'opaque'}

कोई mode: 'opaque'अनुरोध मोड नहीं है - opaqueइसके बजाय केवल प्रतिक्रिया की एक संपत्ति है , और ब्राउज़र ने no-corsमोड के साथ भेजे गए अनुरोधों से प्रतिक्रियाओं पर उस अपारदर्शी संपत्ति को सेट किया है।

लेकिन संयोगवश अपारदर्शी शब्द आपके द्वारा समाप्त की गई प्रतिक्रिया की प्रकृति के बारे में एक बहुत स्पष्ट संकेत है: "अपारदर्शी" इसका मतलब है कि आप इसे नहीं देख सकते हैं।


4
cors-anywhereसरल गैर-ठेस उपयोग के मामलों (यानी कुछ सार्वजनिक रूप से उपलब्ध डेटा प्राप्त करना) के लिए वर्कअराउंड से प्यार करें । यह उत्तर मेरे संदेह की पुष्टि करता है जो no-corsसामान्य नहीं है क्योंकि इसका OpaqueResponse बहुत उपयोगी नहीं है; "बहुत सीमित मामले"; क्या कोई मुझे उदाहरण समझा सकता है जहाँ no-corsउपयोगी है?
लाल मटर

1
@TheRedPea अद्यतन मैं यहाँ जवाब देने के लिए बनाया देखें (और है कि मैं भी पर अपने प्रश्न के लिए टिप्पणी के रूप में जोड़ा stackoverflow.com/questions/52569895/... )
sideshowbarker

मुझे अपने एक्सप्रेस सर्वर को CORS.js पैकेज - github.com/expressjs/cors के साथ कॉन्फ़िगर करने की आवश्यकता थी - और फिर मुझे भ्रूण mode: 'no-cors'अनुरोध (अन्यथा प्रतिक्रिया खाली होगी) से निकालने की आवश्यकता थी
जेम्स एल।

कॉर्स प्रॉक्सी बढ़िया है। मुझे आश्चर्य है कि इसे सार्वजनिक फ़ाइलों तक पहुँच को अवरुद्ध करने के लिए "सुरक्षा" उपाय माना जाता है। हैकर के नजरिए से इधर-उधर जाना इतना आसान है, और ठीक यही है। यह वास्तव में अच्छे अभिनेताओं के लिए सिर्फ एक परेशानी है।
सिपाही रीड

मैं एक ही एपीआई का उपभोग करने वाले विभिन्न ग्राहकों का कोड तैयार करता हूं। मैं इसका इस्तेमाल ट्रेनिंग के लिए करता हूं। मैं कोड को सरल रखना चाहता हूं और उपयोगकर्ताओं को इसके साथ खेलना चाहता हूं। मुझे नो-क्रोस का उपयोग करने की आवश्यकता है।
profimedica

6

इसलिए यदि आप मेरे जैसे हैं और लोकलहोस्ट पर एक वेबसाइट विकसित कर रहे हैं, जहाँ आप लारवेल एपीआई से डेटा प्राप्त करने का प्रयास कर रहे हैं और अपने Vue फ्रंट-एंड में इसका उपयोग कर रहे हैं, और आप इस समस्या को देखते हैं, यहाँ बताया गया है कि मैंने इसे कैसे हल किया:

  1. अपने Laravel प्रोजेक्ट में, कमांड चलाएँ php artisan make:middleware Cors। यह app/Http/Middleware/Cors.phpआपके लिए पैदा करेगा ।
  2. handlesफ़ंक्शन के अंदर निम्न कोड जोड़ें Cors.php:

    return $next($request)
        ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  3. में app/Http/kernel.php, जोड़ने में निम्नलिखित प्रविष्टि $routeMiddlewareसरणी:

    cors => \App\Http\Middleware\Cors::class

    (सरणी में अन्य प्रविष्टियाँ होंगी जैसे auth, guestआदि भी सुनिश्चित करें कि आप ऐसा कर रहे हैं app/Http/kernel.phpक्योंकि kernel.phpलारवेल में एक और भी है)

  4. उन सभी मार्गों के लिए मार्ग पंजीकरण पर इस मिडलवेयर को जोड़ें जहां आप इस तरह से पहुंच की अनुमति देना चाहते हैं:

    Route::group(['middleware' => 'cors'], function () {
        Route::get('getData', 'v1\MyController@getData');
        Route::get('getData2', 'v1\MyController@getData2');
    });
  5. Vue फ्रंट-एंड में, सुनिश्चित करें कि आप इस API को mounted()फ़ंक्शन में कहते हैं और अंदर नहीं data()। यह भी सुनिश्चित करें कि आप अपने कॉल में URL का उपयोग करते हैं http://या कर रहे हैं ।https://fetch()

पीट ह्यूस्टन के ब्लॉग लेख का पूरा श्रेय ।


3

सरल समाधान: आप जिस php फ़ाइल से डेटा का अनुरोध कर रहे हैं, उसके शीर्ष पर निम्नलिखित जोड़ें।

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


7
यह एक बहुत अच्छा विचार है अगर आप कम से कम सुरक्षा संभव चाहते हैं :)।
हेट्रिक बंदर


1

मेरे लिए समाधान सिर्फ सर्वर साइड में करना था

मैंने WebClientडेटा प्राप्त करने के लिए C (लाइब्रेरी का उपयोग किया था (मेरे मामले में यह छवि डेटा था) और इसे क्लाइंट को वापस भेजें। आपकी चुनी हुई सर्वर-साइड भाषा में संभवतः बहुत कुछ समान है।

//Server side, api controller

[Route("api/ItemImage/GetItemImageFromURL")]
public IActionResult GetItemImageFromURL([FromQuery] string url)
{
    ItemImage image = new ItemImage();

    using(WebClient client = new WebClient()){

        image.Bytes = client.DownloadData(url);

        return Ok(image);
    }
}

आप इसे जो कुछ भी अपने खुद के उपयोग के मामले में ट्विक कर सकते हैं। मुख्य बिंदु client.DownloadData()बिना किसी कोर त्रुटियों के काम किया जाता है । आमतौर पर CORS मुद्दे केवल वेबसाइटों के बीच होते हैं, इसलिए आपके सर्वर से 'क्रॉस-साइट' अनुरोध करना ठीक है।

फिर रिएक्ट लाने के लिए कॉल सरल है:

//React component

fetch(`api/ItemImage/GetItemImageFromURL?url=${imageURL}`, {            
        method: 'GET',
    })
    .then(resp => resp.json() as Promise<ItemImage>)
    .then(imgResponse => {

       // Do more stuff....
    )}

1

बहुत आसान समाधान (2 मिनट से कॉन्फ़िगर) से स्थानीय-एसएसएल-प्रॉक्सी पैकेज का उपयोग करना हैnpm

उपयोग सीधे बहुत आगे है:
1. पैकेज स्थापित करें: npm install -g local-ssl-proxy
2. अपने local-serverमास्क को चलाते हुएlocal-ssl-proxy --source 9001 --target 9000

पुनश्च: के--target 9000 साथ -- "number of your port"और के --source 9001साथ बदलें--source "number of your port +1"


1
मुझे असली फोन डिवाइस में अपने ऐप का उपयोग करने में समस्या है। क्या आपका समाधान इस मामले के लिए सहायक है?
हामिद अराघी

@ HamidAraghi मुझे लगता है कि अब, विकासशील उद्देश्यों के लिए प्रॉक्सी सर्वर को उस उपकरण पर चलना चाहिए जो वास्तव में त्रुटि से प्रभावित है
volna
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.