मेरे जावास्क्रिप्ट कोड को "नहीं 'एक्सेस-कंट्रोल-अलाउंस-ओरिजिन' हेडर अनुरोधित संसाधन पर मौजूद है।"
मॉड नोट : यह प्रश्न इस बारे में है कि पोस्टमैन उसी तरह एक XMLHttpRequest को कोर प्रतिबंधों के अधीन क्यों नहीं है। यह प्रश्न "नो 'एक्सेस-कंट्रोल-अलाउंस-ओरिजिन ..." को ठीक करने के तरीके के बारे में नहीं है ।
कृपया पोस्ट करना बंद करें :
- सूर्य के नीचे हर भाषा / ढांचे के लिए CORS विन्यास। इसके बजाय अपनी प्रासंगिक भाषा / रूपरेखा का प्रश्न खोजें ।
- 3 पार्टी सेवाएं जो कॉर्स को दरकिनार करने का अनुरोध करती हैं
- विभिन्न ब्राउज़रों के लिए कॉर्स को बंद करने के लिए कमांड लाइन विकल्प
मैं RESTful API बिल्ट-इन फ्लास्क से कनेक्ट करके जावास्क्रिप्ट का उपयोग करके प्राधिकरण करने की कोशिश कर रहा हूं । हालाँकि, जब मैं अनुरोध करता हूं, मुझे निम्नलिखित त्रुटि मिलती है:
XMLHttpRequest लोड नहीं किया जा सकता है http://myApiUrl/login। अनुरोधित संसाधन पर कोई 'एक्सेस-कंट्रोल-अनुमति-उत्पत्ति' हेडर मौजूद नहीं है। उत्पत्ति 'अशक्त' इसलिए पहुंच की अनुमति नहीं है।
मुझे पता है कि एपीआई या दूरस्थ संसाधन हेडर को सेट करना होगा, लेकिन जब मैंने क्रोम एक्सटेंशन पोस्टमैन के माध्यम से अनुरोध किया था तो यह काम क्यों किया था ?
यह अनुरोध कोड है:
$.ajax({
type: "POST",
dataType: 'text',
url: api,
username: 'user',
password: 'pass',
crossDomain : true,
xhrFields: {
withCredentials: true
}
})
.done(function( data ) {
console.log("done");
})
.fail( function(xhr, textStatus, errorThrown) {
alert(xhr.responseText);
alert(textStatus);
});
जवाब
अगर मुझे यह ठीक से समझ में आ गया है कि आप XMLHttpRequest एक अलग डोमेन पर कर रहे हैं तो आपका पेज चालू है इसलिए ब्राउज़र इसे अवरुद्ध कर रहा है क्योंकि यह आमतौर पर सुरक्षा कारणों के लिए एक ही मूल में अनुरोध की अनुमति देता है। जब आप क्रॉस-डोमेन अनुरोध करना चाहते हैं तो आपको कुछ अलग करना होगा। कैसे प्राप्त करने के बारे में एक ट्यूटोरियल कॉर्स का उपयोग कर रहा है ।
जब आप पोस्टमैन का उपयोग कर रहे हैं तो वे इस नीति द्वारा प्रतिबंधित नहीं हैं। क्रॉस-ओरिजिन XMLHttpRequest से उद्धृत :
नियमित वेब पेज दूरस्थ सर्वर से डेटा भेजने और प्राप्त करने के लिए XMLHttpRequest ऑब्जेक्ट का उपयोग कर सकते हैं, लेकिन वे एक ही मूल नीति द्वारा सीमित हैं। एक्सटेंशन इतने सीमित नहीं हैं। एक एक्सटेंशन अपने मूल के बाहर के दूरस्थ सर्वरों से बात कर सकता है, जब तक कि वह पहली बार क्रॉस-ऑरिजिन अनुमतियों का अनुरोध करता है।
चेतावनी: का उपयोग करते हुए
Access-Control-Allow-Origin: *
अपने एपीआई / वेबसाइट कमजोर करने के लिए कर सकते हैं क्रॉस साइट अनुरोध जालसाजी (CSRF) हमला करता है। सुनिश्चित करें कि आप इस कोड का उपयोग करने से पहले जोखिमों को समझते हैं ।
यदि आप PHP का उपयोग कर रहे हैं तो यह हल करना बहुत आसान है । बस अपने PHP पेज की शुरुआत में निम्नलिखित स्क्रिप्ट जोड़ें जो अनुरोध को संभालती है:
<?php header('Access-Control-Allow-Origin: *'); ?>
यदि आप Node-red का उपयोग कर रहे हैं, तो आपको निम्नलिखित पंक्तियों को अन-कमेंट करके फाइल में CORS की अनुमति देनी होगी node-red/settings.js
:
// The following property can be used to configure cross-origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
origin: "*",
methods: "GET,PUT,POST,DELETE"
},
यदि आप फ्लास्क का उपयोग प्रश्न के समान कर रहे हैं ; आपको पहले स्थापित करना हैflask-cors
$ pip install -U flask-cors
फिर अपने आवेदन में फ्लास्क कोर शामिल करें।
from flask_cors import CORS
एक साधारण आवेदन की तरह दिखेगा:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/")
def helloWorld():
return "Hello, cross-origin-world!"
अधिक जानकारी के लिए, आप फ्लास्क प्रलेखन की जांच कर सकते हैं ।
क्योंकि
$ .ajax ({प्रकार: "POST" - विकल्प
$ .post ( - कॉल POST) कहता है
दोनों अलग हैं। पोस्टमैन "POST" को ठीक से कॉल करता है, लेकिन जब हम इसे कॉल करते हैं, तो यह "विकल्प" होगा।
सी # वेब सेवाओं के लिए - वेब एपीआई
कृपया <system.webServer> टैग के तहत अपने web.config फ़ाइल में निम्न कोड जोड़ें । यह काम करेगा:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
कृपया सुनिश्चित करें कि आप अजाक्स कॉल में कोई गलती नहीं कर रहे हैं
jQuery
$.ajax({
url: 'http://mysite.microsoft.sample.xyz.com/api/mycall',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
type: "POST", /* or type:"GET" or type:"PUT" */
dataType: "json",
data: {
},
success: function (result) {
console.log(result);
},
error: function () {
console.log("error");
}
});
नोट: यदि आप किसी तृतीय-पक्ष वेबसाइट से सामग्री डाउनलोड करने के लिए देख रहे हैं तो यह आपकी मदद नहीं करेगा । आप निम्न कोड आज़मा सकते हैं, लेकिन जावास्क्रिप्ट नहीं।
System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.microsoft.sample.xyz.com/api/mycall");
एपीआई के रूप में नीचे की जांच में, मैं उपयोग करता हूं http://example.com के बजाय http://myApiUrl/login आपके सवाल से, क्योंकि यह पहला काम है।
मुझे लगता है कि आपका पृष्ठ चालू है http://my-site.local:8088।
अलग-अलग परिणाम देखने का कारण यह है कि पोस्टमैन:
- हेडर सेट करें
Host=example.com
(आपका एपीआई) - हेडर सेट नहीं है
Origin
यह ब्राउज़र के अनुरोध भेजने के तरीके के समान है जब साइट और एपीआई में एक ही डोमेन होता है (ब्राउज़र हेडर आइटम भी सेट करता है Referer=http://my-site.local:8088
, हालांकि मैं इसे पोस्टमैन में नहीं देखता हूं)। जब Origin
हेडर सेट नहीं होता है, तो आमतौर पर सर्वर डिफ़ॉल्ट रूप से ऐसे अनुरोधों की अनुमति देते हैं।
यह मानक तरीका है कि पोस्टमैन अनुरोध कैसे भेजता है। लेकिन जब आपकी साइट और API में अलग-अलग डोमेन होते हैं , तो एक ब्राउज़र अलग-अलग अनुरोध भेजता है , और फिर CORS होता है और ब्राउज़र स्वचालित रूप से होता है:
- हेडर सेट करता है
Host=example.com
(आपका एपीआई के रूप में) - शीर्ष लेख
Origin=http://my-site.local:8088
(आपकी साइट)
(हेडर के रूप Referer
में एक ही मूल्य है Origin
)। और अब क्रोम के कंसोल और नेटवर्क टैब में आप देखेंगे:
जब आपके पास Host != Origin
यह कॉर्स है, और जब सर्वर इस तरह के अनुरोध का पता लगाता है, तो यह आम तौर पर इसे डिफ़ॉल्ट रूप से ब्लॉक करता है ।
Origin=null
जब आप HTML सामग्री को किसी स्थानीय निर्देशिका से खोलते हैं, और यह एक अनुरोध भेजता है। ऐसी ही स्थिति तब होती है जब आप <iframe>
नीचे दिए गए स्निपेट की तरह एक अनुरोध भेजते हैं (लेकिन यहां Host
हेडर बिल्कुल सेट नहीं है) - सामान्य तौर पर, हर जगह HTML विनिर्देशन अपारदर्शी मूल कहता है, आप इसका अनुवाद कर सकते हैं Origin=null
। इसके बारे में अधिक जानकारी आप यहां पा सकते हैं ।
fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab
यदि आप एक साधारण कोर अनुरोध का उपयोग नहीं करते हैं, तो आमतौर पर ब्राउज़र स्वचालित रूप से मुख्य अनुरोध भेजने से पहले एक विकल्प अनुरोध भी भेजता है - अधिक जानकारी यहां है । नीचे दिया गया स्निपेट यह दिखाता है:
fetch('http://example.com/api', {
method: 'POST',
headers: { 'Content-Type': 'application/json'}
});
Look in chrome-console -> network tab to 'api' request.
This is the OPTIONS request (the server does not allow sending a POST request)
आप CORS अनुरोधों की अनुमति देने के लिए अपने सर्वर के कॉन्फ़िगरेशन को बदल सकते हैं।
यहां एक उदाहरण कॉन्फ़िगरेशन है जो कॉर्न्स को nginx (nginx.conf फ़ाइल) पर चालू करता है - always/"$http_origin"
nginx के लिए सेटिंग के साथ बहुत सावधान रहें और "*"
Apache के लिए - यह किसी भी डोमेन से CORS को अनब्लॉक करेगा।
location ~ ^/index\.php(/|$) {
...
add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Credentials' 'true' always; if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
}
यहाँ एक उदाहरण विन्यास है जो अपाचे (.htaccess फ़ाइल) पर CORS को चालू करता है
# ------------------------------------------------------------------------------
# | Cross-domain Ajax requests |
# ------------------------------------------------------------------------------
# Enable cross-origin Ajax requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/
# <IfModule mod_headers.c>
# Header set Access-Control-Allow-Origin "*"
# </IfModule>
# Header set Header set Access-Control-Allow-Origin "*"
# Header always set Access-Control-Allow-Credentials "true"
Access-Control-Allow-Origin "http://your-page.com:80"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"
एक CorS प्रतिबंध लागू करना एक सुरक्षा सुविधा है जो एक सर्वर द्वारा परिभाषित है और एक ब्राउज़र द्वारा कार्यान्वित की जाती है ।
ब्राउज़र सर्वर की CORS नीति को देखता है और उसका सम्मान करता है।
हालाँकि, पोस्टमैन उपकरण सर्वर के कोर नीति के बारे में परेशान नहीं करता है।
यही कारण है कि ब्राउज़र में CORS त्रुटि दिखाई देती है, लेकिन पोस्टमैन में नहीं।
विभिन्न उपयोग के मामले में एक ही त्रुटि का सामना करना पड़ा।
केस का उपयोग करें: क्रोम में जब स्प्रिंग रेस्ट एंड पॉइंट को कोणीय में बुलाने की कोशिश की जाती है ।
समाधान: संबंधित नियंत्रक वर्ग के शीर्ष पर @CrossOrigin ("*") एनोटेशन जोड़ें ।
यदि आप जावास्क्रिप्ट में लाने के लिए कंटेंट को लाने के दौरान उस प्रतिबंध को बायपास करना चाहते हैं या जावास्क्रिप्ट में XMLHttpRequest, तो आप एक प्रॉक्सी सर्वर का उपयोग कर सकते हैं ताकि यह हेडर Access-Control-Allow-Origin
को सेट कर दे *
।
const express = require('express');
const request = require('request');
const app = express();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
app.get('/fetch', (req, res) => {
request(
{ url: req.query.url },
(error, response, body) => {
if (error || response.statusCode !== 200) {
return res.status(500).send('error');
}
res.send(body);
}
)
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`listening on ${PORT}`));
ऊपर एक नमूना कोड (नोड जेएस आवश्यक है) जो एक प्रॉक्सी सर्वर के रूप में कार्य कर सकता है। उदाहरण के लिए: यदि मैं https://www.google.com
सामान्य रूप से एक CorS त्रुटि लाना चाहता हूं , लेकिन अब चूंकि अनुरोध 3000 पोर्ट पर स्थानीय स्तर पर होस्ट किए गए प्रॉक्सी सर्वर के माध्यम से भेजा जाता है, तो प्रॉक्सी सर्वर Access-Control-Allow-Origin
प्रतिक्रिया में हेडर जोड़ता है और इसमें कोई समस्या नहीं होती है।
Http: // localhost: 3000 / fetch? Url = के लिए GET अनुरोध भेजें Your URL here
, इसके बजाय सीधे URL के अनुरोध को भेजने के लिए जिसे आप प्राप्त करना चाहते हैं।
Your URL here
उस URL के लिए खड़ा है जिसे आप प्राप्त करना चाहते हैं जैसे: https://www.google.com
केवल .NET कोर वेब एपीआई परियोजना के लिए, निम्नलिखित परिवर्तन जोड़ें:
- Startup.cs फ़ाइल
services.AddMvc()
कीConfigureServices()
विधि में लाइन के बाद निम्न कोड जोड़ें :
services.AddCors(allowsites=>{allowsites.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
});
- Startup.cs फ़ाइल
app.UseMvc()
कीConfigure()
विधि में लाइन के बाद निम्न कोड जोड़ें :
app.UseCors(options => options.AllowAnyOrigin());
- उस नियंत्रक को खोलें जिसे आप डोमेन के बाहर एक्सेस करना चाहते हैं और नियंत्रक स्तर पर इस विशेषता को जोड़ें:
[EnableCors("AllowOrigin")]