I'm mencoba untuk mengambil beberapa data dari SISA API dari HP Alm. Ia bekerja cukup baik dengan sedikit curl script - saya mendapatkan data.
Sekarang melakukan hal itu dengan JavaScript, mengambil dan ES6 (lebih atau kurang) tampaknya menjadi masalah yang lebih besar. Saya terus mendapatkan pesan kesalahan ini:
Mengambil API tidak dapat memuat
. Menanggapi preflight permintaan doesn't lulus akses kontrol check: Tidak ada 'Access-Control-Allow-Origin' header hadir pada sumber daya yang diminta. Asal 'http://127.0.0.1:3000' adalah oleh karena itu tidak diperbolehkan mengakses. Respon punya kode status HTTP 501. Jika buram respon melayani kebutuhan anda, mengatur permintaan's mode untuk 'tidak ada-cors' untuk mengambil sumber daya dengan CORS dinonaktifkan.
Saya memahami bahwa ini adalah karena saya mencoba untuk mengambil data dari dalam saya localhost dan solusinya harus menggunakan CORS. Sekarang saya pikir saya benar-benar melakukan itu, tapi entah bagaimana itu mengabaikan apa yang saya tulis di header atau masalah adalah sesuatu yang lain?
Jadi, ada sebuah implementasi masalah? Saya lakukan itu salah? Saya dapat't memeriksa log server sayangnya. I'm benar-benar sedikit terjebak di sini.
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('GET', 'POST', 'OPTIONS');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
fetch(sign_in, {
//mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
Saya menggunakan Chrome. Saya juga mencoba menggunakan Chrome CORS Plugin, tapi kemudian saya mendapatkan pesan kesalahan lain:
nilai 'Access-Control-Allow-Origin' header di respon tidak harus wildcard '*' ketika permintaan's kredensial mode 'termasuk'. Asal 'http://127.0.0.1:3000' oleh karena itu tidak diperbolehkan akses. Kredensial modus permintaan yang diprakarsai oleh XMLHttpRequest dikendalikan oleh withCredentials atribut.
Jawaban ini mencakup banyak tanah, sehingga hal ini dibagi menjadi tiga bagian:
Bagaimana untuk menggunakan CORS proxy untuk mendapatkan sekitar "Tidak ada Akses-Kontrol-Allow-Origin header" masalah
Jika anda tidak mengontrol server anda frontend kode JavaScript adalah mengirimkan permintaan, dan masalah dengan respon dari server adalah kurangnya diperlukan Access-Control-Allow-Origin
header, anda masih bisa mendapatkan hal-hal untuk bekerja—dengan membuat permintaan melalui CORS proxy. Untuk menunjukkan bagaimana cara kerjanya, pertama berikut ini beberapa kode yang tidak menggunakan CORS proxy:
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(url)
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
Alasan menangkap
block mendapat untung ada, browser mencegah kode yang mengakses respon yang datang kembali dari https://example.com
. Dan alasan browser tidak itu adalah, respon yang tidak memiliki Akses-Kontrol-Allow-Origin
respon header.
Sekarang, di sini sama persis dengan contoh yang sama tapi hanya dengan CORS proxy ditambahkan dalam:
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(proxyurl + url) // https://cors-anywhere.herokuapp.com/https://example.com
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
Catatan: Jika https
https://example.com
. https://example.com
. Access-Control-Allow-Origin
header respon. Access-Control-Allow-Origin
respon header apa browser yang melihat.
Anda dapat dengan mudah menjalankan proxy anda sendiri menggunakan kode dari https://github.com/Rob--W/cors-anywhere/.git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
https://cors-anywhere.herokuapp.com
, awalan itu bukan dengan URL anda sendiri contoh; misalnya, https://cryptic-headland-94862.herokuapp.com/https://example.com.
Jadi, jika ketika anda pergi untuk mencoba untuk menggunakan httpsPILIHAN
permintaan—karena dalam kasus itu, proxy juga mengirimkan kembali Access-Control-Memungkinkan-Header
dan Access-Control-Memungkinkan-Metode
header yang dibutuhkan untuk membuat preflight sukses. Bagaimana untuk menghindari CORS preflight
Kode pada pertanyaan pemicu CORS preflight—sejak itu mengirimkan sebuah Otorisasi
header.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
Bahkan tanpa itu, Content-Type: application/json
header juga akan memicu preflight.
Apa "preflight" berarti: sebelum browser mencoba POST
pada kode di atas, hal pertama yang akan mengirim sebuah PILIHAN
permintaan ke server — untuk menentukan apakah server adalah memilih-in untuk menerima salib-asal POST
yang mencakup Otorisasi
dan Content-Type: application/json
header.
Ini bekerja dengan cukup baik dengan sedikit curl script - saya mendapatkan data. Untuk benar menguji dengan
keriting
, anda perlu meniru preflightPILIHAN
permintaan browser akan mengirimkan:
curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"
...dengan https://the.sign_in.url
digantikan oleh apapun anda sebenarnya sign_in
URL.
Respon browser kebutuhan untuk melihat bahwa PILIHAN
permintaan harus mencakup header seperti ini:
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
Jika PILIHAN
respon tidak termasuk orang-orang header, maka browser akan berhenti di sana dan bahkan tidak pernah mencoba untuk mengirim permintaan POST
. Juga, kode status HTTP untuk respon harus 2xx—biasanya 200 atau 204. Jika itu yang lain kode status, browser akan berhenti di sana.
Server dalam pertanyaan adalah menanggapi PILIHAN
permintaan dengan 501 kode status, yang tampaknya berarti itu mencoba untuk menunjukkan itu tidak melaksanakan dukungan untuk PILIHAN
permintaan. Lainnya server biasanya merespon dengan 405 "Metode tidak diizinkan" kode status dalam kasus ini.
Jadi anda tidak akan pernah mampu membuat POST
permintaan secara langsung ke server tersebut dari frontend anda kode JavaScript jika server merespon bahwa PILIHAN
permintaan dengan 405 atau 501 atau sesuatu yang lain dari 200 atau 204 atau jika tidak merespon dengan orang-orang yang diperlukan respon header.
Cara untuk menghindari memicu preflight untuk kasus dalam pertanyaan akan sama:
Otorisasi
header permintaan, tetapi bukan (misalnya) bergantung pada data otentikasi tertanam dalam tubuh POST
permintaan atau sebagai parameter kueri POST
tubuh untuk memiliki Content-Type: application/json
jenis media tapi bukannya menerima POST
tubuh application/x-www-form-urlencoded
dengan parameter bernama json
(atau apapun) yang nilainya adalah JSON data Cara untuk memperbaiki kesalahan "Access-Control-Allow-Origin header tidak harus wildcard" masalah
saya mendapatkan pesan kesalahan lain:
nilai 'Access-Control-Allow-Origin' header di respon tidak harus wildcard '' ketika permintaan's kredensial mode 'termasuk'. Asal 'http://127.0.0.1:3000' oleh karena itu tidak diperbolehkan akses. Kredensial modus permintaan yang diprakarsai oleh XMLHttpRequest dikendalikan oleh withCredentials atribut. Untuk permintaan yang mencakup kepercayaan, browser tidak akan membiarkan anda frontend kode JavaScript mengakses respon jika nilai
Access-Control-Allow-Origin
respon header `. Alih-nilai dalam kasus itu harus sama persis frontend anda kode origin,
http://127.0.0.1:3000. Lihat [*Dipercayai permintaan dan wildcard*][1] di MDN HTTP access control (CORS) artikel. Jika anda mengontrol server anda mengirimkan permintaan, maka cara yang umum untuk menangani hal ini adalah untuk mengkonfigurasi server untuk mengambil nilai dari
Asalheader permintaan, dan echo/mencerminkan bahwa kembali ke nilai
Access-Control-Allow-Origin` respon header. Misalnya, dengan nginx:
add_header Access-Control-Allow-Origin $http_origin
saya menggunakan Chrome. Saya juga mencoba menggunakan Chrome CORS Plugin Bahwa Chrome CORS plugin rupanya hanya simplemindedly menyuntikkan
Access-Control-Allow-Origin: *
header menjadi respon browser yang melihat. Jika plugin yang cerdas, apa yang akan lakukan adalah menetapkan nilai yang palsuAccess-Control-Allow-Origin
respon header yang sebenarnya asal anda frontend kode JavaScript,http://127.0.0.1:3000
. Jadi hindari menggunakan plugin itu, bahkan untuk pengujian. Itu hanya pengalih perhatian. Jika anda ingin menguji apa tanggapan anda dapatkan dari server dengan browser penyaringan mereka, anda lebih baik menggunakancurl -Jam
seperti di atas.Sejauh frontend kode JavaScript untuk
mengambil(...)
permintaan pada pertanyaan:
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
Menghilangkan garis-garis. Access-Control-Memungkinkan-*
header respon header. Anda tidak pernah ingin mengirim mereka dalam permintaan. Satu-satunya efek yang akan memiliki adalah untuk memicu sebuah browser untuk melakukan preflight.
Kesalahan ini terjadi ketika klien URL dan URL server don't pertandingan, termasuk nomor port. Dalam hal ini anda perlu mengaktifkan layanan anda untuk CORS yang merupakan cross asal berbagi sumber daya.
Jika anda hosting sebuah musim Semi ISTIRAHAT layanan maka anda dapat menemukannya di dalam blog post CORS dukungan di Spring Framework.
Jika anda hosting sebuah layanan yang menggunakan Node.js server kemudian
npm install cors-simpan
var cors = require('cors')
aplikasi.menggunakan(cors()) // Gunakan ini setelah deklarasi variabel
Masalah muncul karena anda menambahkan kode berikut sebagai permintaan header di front-end :
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
Orang-orang header milik respon, bukan permintaan. Jadi menghapus mereka, termasuk line :
headers.append('GET', 'POST', 'OPTIONS');
Permintaan anda telah 'Content-Type: application/json', maka memicu apa yang disebut CORS preflight. Hal ini disebabkan browser mengirim permintaan dengan PILIHAN metode. Lihat CORS preflight untuk informasi rinci.
Oleh karena itu di back-end, anda harus menangani hal ini preflighted permintaan dengan kembali respon header yang meliputi :
Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, OPTIONS
Access-Control-Allow-Headers : Origin, Content-Type, Accept
Tentu saja, sebenarnya sintaks tergantung pada bahasa pemrograman yang anda gunakan untuk back-end.
Di front-end, hal ini harus menjadi seperti ini :
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
headers.append('Origin','http://localhost:3000');
fetch(sign_in, {
mode: 'cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
Dalam kasus saya, saya menggunakan solusi di bawah ini
Front-end atau Sudut
post(
this.serverUrl, dataObjToPost,
{
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
}
)
back-end (saya menggunakan php)
header("Access-Control-Allow-Origin: http://localhost:4200");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header("Access-Control-Allow-Headers: Content-Type, Authorization");
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
print_r($request);
Just my two cents... mengenai Cara menggunakan CORS proxy untuk mendapatkan sekitar "Tidak ada Access-Control-Allow-Origin
header" masalah
Bagi anda yang bekerja dengan php di backend, menyebarkan "CORS proxy" adalah yang sederhana seperti:
$URL = $_GET['url']; echo json_encode(file_get_contents($URL)); die();
fetch('https://example.com/no-cors.php' + '?url=' + url) .kemudian(respon=>{*/Menangani Respon/*})
Dalam kasus saya, web server dicegah "PILIHAN" metode
Cek web server untuk pilihan metode
I'm menggunakan "webtier"
/www/webtier/domain/[namadomain]/config/fmwconfig/komponen/OHS/VCWeb1/httpd.conf
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_METHOD} ^OPTIONS
RewriteRule .* . [F]
</IfModule>
perubahan
<IfModule mod_rewrite.c>
RewriteEngine off
RewriteCond %{REQUEST_METHOD} ^OPTIONS
RewriteRule .* . [F]
</IfModule>
Menggunakan dataType: 'jsonp'
bekerja untuk saya.
async function get_ajax_data(){
var _reprojected_lat_lng = await $.ajax({
type: 'GET',
dataType: 'jsonp',
data: {},
url: _reprojection_url,
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR)
},
success: function (data) {
console.log(data);
// note: data is already json type, you
// just specify dataType: jsonp
return data;
}
});
} // function
Saya bekerja dengan musim Semi ISTIRAHAT, dan saya soal itu menambahkan AllowedMethods ke WebMvcConfigurer.
@Value( "${app.allow.origins}" )
private String allowOrigins;
@Bean
public WebMvcConfigurer corsConfigurer() {
System.out.println("allow origin: "+allowOrigins);
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
//.allowedOrigins("http://localhost")
.allowedOrigins(allowOrigins)
.allowedMethods("PUT", "DELETE","GET", "POST");
}
};
}
Tercepat memperbaiki anda dapat membuat adalah untuk menginstal moesif CORS ekstensi .
https://chrome.google.com/webstore/detail/moesif-orign-cors-changer/digfbfaphojjndkpccljibejjbppifbc?hl=en-US
Setelah diinstal, klik di browser anda untuk mengaktifkan ekstensi. Pastikan ikon label pergi dari "off" untuk "on"; Kemudian refresh aplikasi anda, dan anda permintaan API sekarang harus bekerja! Plugin pasti membahas masalah ini. Namun, perbaikan ini hanya berlaku untuk mesin anda sendiri. Dalam pembangunan daerah, itu baik untuk memiliki sebuah plugin yang diinstal yang dapat membantu anda mendapatkan lalu kesalahan.