jQuery এক্সএমএল ত্রুটি 'না' অ্যাক্সেস-কন্ট্রোল-অলজন-অরিজিন 'শিরোনাম অনুরোধকৃত উত্সটিতে উপস্থিত রয়েছে।'


89

আমি এই ব্যাক্তিগত প্রকল্পটিতে কেবল মজাদার জন্য কাজ করছি যেখানে আমি একটি এক্সএমএল ফাইল পড়তে চাই যেখানে http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml এ অবস্থিত এবং এক্সএমএল এবং পার্স করতে পারি মুদ্রার মধ্যে মান রূপান্তর করতে এটি ব্যবহার করুন।

এখন পর্যন্ত আমি নীচের কোডটি নিয়ে এসেছি যা এক্সএমএল পড়ার জন্য বেশ বেসিক তবে আমি নিম্নলিখিত ত্রুটিটি পেয়েছি।

XMLHttpRequest **** লোড করতে পারে না load অনুরোধকৃত উত্সটিতে কোনও 'অ্যাক্সেস-কন্ট্রোল-মঞ্জুরি-উত্স' শিরোনাম উপস্থিত নেই। মূল ' http://run.jsbin.com ' এ অ্যাক্সেসের অনুমতি নেই।

$(document).ready( 
    function() {     
        $.ajax({          
            type:  'GET',
            url:   'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
            dataType: 'xml',              
            success: function(xml){
                alert('aaa');
            }
         });
    }
);

আমি আমার কোডটিতে কোনও ভুল দেখতে পাচ্ছি না তাই আমি আশা করছি যে কেউ আমার কোডটি দিয়ে কী ভুল করছে এবং আমি কীভাবে এটি সংশোধন করতে পারি তা নির্দেশ করতে পারে।


4
আমি আপনাকে পরামর্শ দিচ্ছি আপনি কোন বিষয়ে পড়তে একই অরিজিন নীতি এবং CORS
jmoerdyk

ত্রুটিটি ঠিক কী ভুল, শব্দের জন্য শব্দ বলে states আপনার কোডটি ঠিক আছে, আপনি যে সার্ভারটি অ্যাক্সেস করছেন তাতে সমস্যা।
কেভিন বি

উত্তর:


163

একই-উত্স নীতিমালার কারণে আপনি http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xmlমোতায়েন করা কোনও ফাইল থেকে অজ্যাক্স কল করতে সক্ষম হবেন না ।http://run.jsbin.com


উত্স (ওরফে অরিজিন ) পৃষ্ঠা এবং লক্ষ্য URLটি বিভিন্ন ডোমেন ( run.jsbin.comএবং www.ecb.europa.eu) এ থাকায় আপনার কোডটি আসলে কোনও সাধারণ নয়, ক্রস-ডোমেন (সিওআরএস) অনুরোধ করার চেষ্টা করছে GET

কয়েকটি কথায়, একই-উত্স নীতিতে বলা হয়েছে যে ব্রাউজারগুলির কেবলমাত্র HTML পৃষ্ঠার একই ডোমেনে পরিষেবাতে অজ্যাক্স কলগুলি মঞ্জুরি দেওয়া উচিত ।


উদাহরণ:

এর একটি পৃষ্ঠা http://www.example.com/myPage.htmlকেবলমাত্র সেই জাতীয় পরিষেবার জন্য সরাসরি অনুরোধ করতে http://www.example.comপারে http://www.example.com/api/myService। যদি পরিষেবাটি অন্য কোনও ডোমেনে হোস্ট করা হয় (বলুন http://www.ok.com/api/myService), ব্রাউজারটি সরাসরি কল করবে না (যেমনটি আপনি আশা করেছিলেন)। পরিবর্তে, এটি একটি সিওআরএস অনুরোধ করার চেষ্টা করবে।

এটি শীঘ্রই রাখতে, আপনার ব্রাউজারে বিভিন্ন ডোমেন জুড়ে একটি (সিওআরএস) অনুরোধ সম্পাদন করতে:

  • Originমূল অনুরোধে একটি শিরোনাম অন্তর্ভুক্ত করবে (মান হিসাবে পৃষ্ঠার ডোমেন সহ) এবং এটি যথারীতি সম্পাদন করবে; এবং তারপর
  • শুধু যদি সার্ভার প্রতিক্রিয়া যে অনুরোধ রয়েছে পর্যাপ্ত হেডার ( Access-Control-Allow-Originহয় এক তাদের ) CORS অনুরোধ যার ফলে ব্রাউজ কল (প্রায় ** ঠিক যেভাবে এটা would যদি HTML পাতায় একই ডোমেনে ছিল না) সম্পন্ন করা হবে।
    • যদি প্রত্যাশিত শিরোনাম না আসে, ব্রাউজারটি কেবল ছেড়ে দেয় (যেমনটি এটি আপনাকে করেছিল)।


* উপরেরগুলি একটি সাধারণ অনুরোধে পদক্ষেপগুলি চিত্রিত করে , যেমন GETকোনও অভিনব শিরোনামহীন নিয়মিত । অনুরোধ সহজ না হয়, তাহলে (মত একটি POSTসঙ্গে application/jsonবিষয়বস্তুর প্রকার হিসাবে), ব্রাউজার এটা একটি মুহূর্ত রাখা হবে, এবং, এটা পূরণে আগে, প্রথমে একটি পাঠাব OPTIONSলক্ষ্য URL- এ অনুরোধ। উপরের মত, এটি কেবল তখনই চলতে থাকবে যদি এই OPTIONSঅনুরোধের প্রতিক্রিয়ায় CORS শিরোনাম থাকে। এই OPTIONSকলটি প্রিফ্লাইট অনুরোধ হিসাবে পরিচিত ।
** আমি প্রায় বলছি কারণ নিয়মিত কল এবং সিওআরএস কলগুলির মধ্যে অন্যান্য পার্থক্য রয়েছে। একটি গুরুত্বপূর্ণ হ'ল কিছু শিরোনাম, প্রতিক্রিয়াতে উপস্থিত থাকলেও, ব্রাউজারটি যদি তাদেরAccess-Control-Expose-Headers শিরোনামে অন্তর্ভুক্ত না করা হয় তবে তা বাছাই করা যাবে না


কিভাবে ঠিক হবে এটা?

এটা কি শুধু টাইপো ছিল? কখনও কখনও জাভাস্ক্রিপ্ট কোড লক্ষ্য ডোমেন মধ্যে একটি টাইপো আছে। আপনি চেক করা আছে? পৃষ্ঠাটি যদি থাকে www.example.comতবে কেবলমাত্র নিয়মিত কল করতে হবে www.example.com! অন্যান্য ইউআরএল, যেমন api.example.comবা এমনকি example.comবা ব্রাউজার দ্বারা বিভিন্ন ডোমেন www.example.com:8080হিসাবে বিবেচিত হয়! হ্যাঁ, বন্দরটি যদি আলাদা হয় তবে এটি অন্যরকম ডোমেন!

শিরোনাম যুক্ত করুন। সিওআরএস সক্ষম করার সহজতম উপায় হ'ল Access-Control-Allow-Originসার্ভারের প্রতিক্রিয়াগুলিতে প্রয়োজনীয় শিরোনাম (গুলি ) যুক্ত করা। (প্রতিটি সার্ভার / ভাষার একটি উপায় রয়েছে - এখানে কিছু সমাধান দেখুন )

সর্বশেষ অবলম্বন: যদি আপনার পরিষেবাতে সার্ভার-সাইড অ্যাক্সেস না থাকে তবে আপনি এটিও আয়না করতে পারেন ( রিভার্স প্রক্সির মতো সরঞ্জামগুলির মাধ্যমে ) এবং সেখানে সমস্ত প্রয়োজনীয় শিরোনাম অন্তর্ভুক্ত করতে পারেন।


4
ধন্যবাদ, এটি অনেক তথ্য। এখন আমি এগিয়ে চলার জন্য প্রয়োজনীয় গবেষণা সম্পাদন করতে পারি।
Bazinga777

4
হাই এসিডিজঞ্জিয়র, আমি যে ওয়েব পরিষেবাটিতে অ্যাক্সেস পেতে চাই তা কীভাবে আমি আয়না করব?
ফ্রাঙ্কা

4
@ ফ্রানভা আপনাকে একটি এইচটিটিপি সার্ভার সেট আপ করতে হবে (যেমন টমক্যাট, পিএইচপি সহ অ্যাপাচি, এএসপি সহ আইআইএস) এবং সেখানে একটি পৃষ্ঠা স্থাপন করতে হবে যাতে প্রতিটি অনুরোধের জন্য এটি সকেটটি প্রকৃত পরিষেবায় (যে পরিষেবাটি আপনি মিরর করছেন) খুলবে, প্রকৃত ডেটা অনুরোধ করে এবং তারপরে প্রতিক্রিয়া হিসাবে দেয়। অবশ্যই, আপনি কোডের মাধ্যমে এটি করতে পারবেন (জাভা, পিএইচপি, এএসপি, ইত্যাদি)।
acdcjunior

@acdcjunior দয়া করে আমার সংজ্ঞাটি সঠিক হলে আমাকে সংশোধন করুন। আমি যদি সরাসরি ব্রাউজারে কিছু URL প্রবেশ করি তবে এটি অ্যাক্সেস-নিয়ন্ত্রণ-অনুমতি-উত্স ছাড়াই স্বয়ংক্রিয়ভাবে নতুন ডোমেন url এ পুনঃনির্দেশিত হবে । উদাহরণস্বরূপ, ডাব্লুআইএফ ব্যবহার করার সময়, প্রথমবার লগইন করার সময় ব্যবহারকারীকে তৃতীয় পক্ষের লগইন পৃষ্ঠাতে পুনঃনির্দেশ করা হবে।
মেশিনেরিয়াম

@machinarium আমি নিশ্চিত যদি আমি বুঝতে পারছি তুমি কি বোঝানো, কিন্তু আমি উত্তর (আমাকে বলুন যদি আমি কোন অন্যায় পেয়েছিলাম) করার চেষ্টা করব নই: আপনি ব্রাউজারের ঠিকানা বারে URL, উপস্থিতি বা অনুপস্থিতি লেখেনে Access-Control-Allow-Originযে URL এর শিরোনামে মোটেই কিছু আসে যায় না - ব্রাউজারটি যথারীতি ইউআরএল খুলবে। একই-উত্স নীতি (এবং Access-Control-Allow-Originশিরোনামের জন্য প্রয়োজনীয়তা ) কেবলমাত্র অ্যাজাক্স কলগুলিতে প্রযোজ্য।
acdcjunior

29

আপনি যদি আপনার সার্ভারে পিএইচপি সক্ষম করে থাকেন তবে এটি করার এক ধরণের হ্যাক-কৌশলযুক্ত উপায় রয়েছে। এই লাইনটি পরিবর্তন করুন:

url:   'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',

এই লাইনে:

url: '/path/to/phpscript.php',

এবং তারপরে পিএইচপি স্ক্রিপ্টে (যদি আপনার কাছে ফাইল_জেট_কন্টেন্টস () ফাংশন ব্যবহারের অনুমতি থাকে):

<?php

header('Content-type: application/xml');
echo file_get_contents("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");

?>

পিএইচপি মনে হয় না যে urlটি অন্য কোনও উত্স থেকে এসেছে। যেমনটি আমি বলেছিলাম, এটি হ্যাকি উত্তর, এবং আমি নিশ্চিত যে এটিতে কোনও সমস্যা আছে তবে এটি আমার পক্ষে কার্যকর।

সম্পাদনা করুন: আপনি যদি পিএইচপি-তে ফলাফলটি ক্যাশে করতে চান তবে এই পিএইচপি ফাইলটি আপনি ব্যবহার করবেন:

<?php

$cacheName = 'somefile.xml.cache';
// generate the cache version if it doesn't exist or it's too old!
$ageInSeconds = 3600; // one hour
if(!file_exists($cacheName) || filemtime($cacheName) > time() + $ageInSeconds) {
  $contents = file_get_contents('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml');
  file_put_contents($cacheName, $contents);
}

$xml = simplexml_load_file($cacheName);

header('Content-type: application/xml');
echo $xml;

?>

ক্যাচিং কোডটি এখান থেকে নেওয়া ।


4
এর চেয়ে আরও ভাল সমাধান file_get_contentsহ'ল সার্ভারের পাশে থাকা এক্সএমএল ফাইলটি ক্যাশে করা এবং কেবলমাত্র সাম্প্রতিকতম এক্সএমএল ফাইলের পর্যাপ্ত তারিখ থাকলে কল করা। এছাড়াও, আপনার সামগ্রী-প্রকারের শিরোলেখটি ভুলে যাবেন না :-)
এসএফসিসি

এই উত্তরে হোঁচট খেয়েছে। প্রশ্ন: পিএইচপি ফাইলটি জিইটি ডেটা নিতে এবং উক্ত ইউআরএলে জমা দিতে কীভাবে জানে? এটি কি পোস্ট করা ডেটা দিয়ে কাজ করবে?
এমপিডিসি

এটি জমা দেয় না। এটি ফাইলটি পায় এবং এটি স্থানীয়ভাবে সংরক্ষণ করে, তারপরে এটিকে এমনভাবে ছড়িয়ে দেয় যেন আপনি যে ফাইলটি স্থানীয়ভাবে অনুরোধ করছেন সেই পিএইচপি ফাইল। স্থানীয়ভাবে ক্যাশেড ফাইলটি সর্বাধিক প্রদত্ত বয়সের চেয়ে বেশি বয়সী হলে এটি এর অন্য একটি অনুলিপি পুনরুদ্ধার এবং সংরক্ষণ করবে।
চিন্তাধারা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.