CORS yang mematikan ketika http: // localhost adalah asalnya

186

Saya terjebak dengan masalah CORS ini, meskipun saya mengatur server (nginx / node.js) dengan header yang sesuai.

Saya dapat melihat di panel Jaringan Chrome -> Header Respons:

Access-Control-Allow-Origin:http://localhost

yang seharusnya melakukan trik.

Berikut kode yang sekarang saya gunakan untuk menguji:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
   console.log('xhr loaded');
};
xhr.open('GET', 'http://stackoverflow.com/');
xhr.send();

saya mendapat

XMLHttpRequest tidak dapat memuat http://stackoverflow.com/ . Origin http: // localhost tidak diizinkan oleh Access-Control-Allow-Origin.

Saya menduga itu masalah dalam skrip klien dan bukan konfigurasi server ...

whadar
sumber
44
Tidak, stackoverflow.com perlu mengatur header ini, bukan Anda. : x. Apa yang akan menjadi titik kebijakan asal yang sama jika tidak.
Esailija
3
Coba akses server yang Anda setel agar tidak menumpuk. ;)
Nek
DOH! Apakah ada cara untuk memberi tahu chrome (atau browser lain), untuk mendapatkan sumber daya meskipun headernya tidak ada saat sumber saya adalah localhost?
whadar
Jalankan kode Anda di Chrome (20.0.1132.57, Windows 7), berfungsi dengan baik.
imwilsonxu
1
Jika Anda menggunakan localhost dengan port, jawaban ini berfungsi untuk saya serverfault.com/a/673551/238261 .
Nelu

Jawaban:

230

Chrome tidak mendukung localhost untuk permintaan CORS (bug dibuka pada 2010, ditandai WontFix pada 2014).

Untuk menyiasati ini, Anda dapat menggunakan domain seperti lvh.me(yang menunjuk 127.0.0.1 seperti localhost) atau mulai chrome dengan --disable-web-securitybendera (dengan asumsi Anda hanya menguji).

Pesolek
sumber
24
@greensuisse - ini bukan posting ke localhost. Memposting dari localhost itulah masalahnya.
Cheeso
9
Bug itu tidak valid (dan telah ditandai seperti itu - crbug.com/67743#c17 ). Komentar Esailija benar, menambahkan header ini ke localhost tidak akan secara ajaib memberi Anda akses ke semua situs lain. Ini adalah situs terpencil yang perlu dilayani dengan tajuk ini.
Rob W
22
Hanya menghabiskan 2 jam pengujian pada Chrome untuk menyadari bahwa ia bekerja baik-baik saja di Firefox ..Grrrr...
FloatingRock
11
Pilihan lain: edit file host Anda sehingga lokal. [Situs saya] .com menunjuk ke 127.0.0.1, kemudian buat file CORS Anda memungkinkan *. [Situs saya] .com
tom
6
Saya menghadapi masalah yang sama dengan FireFox. Saya hanya bisa membuatnya di Edge! Posting yang bagus, fantastis! :)
Luis Gouveia
54

Per @ Beau menjawab, Chrome tidak mendukung permintaan CORS localhost, dan tidak mungkin ada perubahan dalam arah ini.

Saya menggunakan Allow-Control-Allow-Origin: * Ekstensi Chrome untuk mengatasi masalah ini. Ekstensi akan menambahkan Header HTTP yang diperlukan untuk CORS:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: "GET, PUT, POST, DELETE, HEAD, OPTIONS"
Access-Control-Expose-Headers: <you can add values here>

The kode sumber dipublikasikan di Github .

Perhatikan bahwa ekstensi memfilter semua URL secara default. Ini dapat merusak beberapa situs web (misalnya: Dropbox). Saya telah mengubahnya untuk memfilter hanya URL host lokal dengan filter URL berikut

*://localhost:*/*
Hanxue
sumber
14
Jika Anda membaca masalah ini, tautan @beau ke Anda akan melihat Chrome 100% mendukung permintaan lintas asal ke dan dari localhost. Masalah ini ditutup pada 2014 karena tidak dapat direproduksi. Sisa kebisingan di utas itu adalah orang-orang dengan server non-asal yang salah konfigurasi (seperti dengan pertanyaan asli di sini).
Molomby
1
Bekerja seperti pesona bagiku di chrome
Aakash Sahai
2
Tautan yang
berfungsi
3
Ekstensi ini tidak berfungsi Access-Control-Allow-Credentials: truekarena disetel Access-Control-Allow-Originke *dan memiliki keduanya trueserta *diblokir oleh browser. Jika menggunakan kredensial benar, Anda harus menggunakan asal non-wildcard. Saya merekomendasikan Moesif Origins dan CORS Changer Extension yang memungkinkan Anda mengubah tajuk sesuai keinginan.
Samuel
Mungkin saya melakukan sesuatu yang salah, tetapi ekstensi ini sepertinya tidak lagi berfungsi untuk saya.
James Parker
19

Masalah sebenarnya adalah bahwa jika kami menetapkan -Allow-untuk semua permintaan ( OPTIONS& POST), Chrome akan membatalkannya. Kode berikut berfungsi untuk saya bersama POSTdengan LocalHost dengan Chrome

<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
    //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header("Access-Control-Allow-Origin: *");
    header('Access-Control-Allow-Credentials: true');    
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
}   
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
} 
?>
greensuisse
sumber
15
OP menggunakan nginx / node.js. Bukan PHP
code_monk
4

Chrome akan membuat permintaan dengan CORS dari a localhost asal saja. Ini bukan masalah dengan Chrome.

Alasan Anda tidak dapat memuat http://stackoverflow.comadalah karena Access-Control-Allow-Origintajuk tidak mengizinkan sumber Anda localhost.

Brad
sumber
2

Perbaikan ekstensi Chrome yang cepat dan kotor:

Moesif Orign & CORS Changer

Namun, Chrome mendukung permintaan lintas asal dari localhost. Pastikan untuk menambahkan tajuk Access-Control-Allow-Originuntuk localhost.

kaleazy
sumber
saya menambahkan ekstensi ini ke Opera saya dan sekarang sudah selesai. saya tidak pernah tahu kapan itu hidup dan mati jadi saya menggunakan firefox untuk bekerja. dan opera untuk pengembangan. Google suit tidak menyukainya, dan hal lain juga tidak.
Maddocks
1

Tidak ada ekstensi yang berfungsi untuk saya, jadi saya memasang proxy lokal sederhana. Dalam kasus saya https://www.npmjs.com/package/local-cors-proxy Ini adalah pengaturan 2 menit:

(dari situs mereka)

npm install -g local-cors-proxy

Titik akhir API yang ingin kami minta yang memiliki masalah CORS: https://www.yourdomain.ie/movies/list

Mulai Proxy: lcp --proxyUrl https://www.yourdomain.ie

Kemudian dalam kode klien Anda, titik akhir API baru: http://localhost:8010/proxy/movies/list

Bekerja seperti pesona bagi saya: aplikasi Anda memanggil proxy, yang memanggil server. Nol masalah CORS.

daniel p
sumber
0

Saya memutuskan untuk tidak menyentuh header dan membuat pengalihan di sisi server sebagai gantinya dan itu wajan seperti pesona.

Contoh di bawah ini adalah untuk versi Angular saat ini (saat ini 9) dan mungkin kerangka kerja lainnya menggunakan webpacks DevServer. Tapi saya pikir prinsip yang sama akan bekerja pada backend lainnya.

Jadi saya menggunakan konfigurasi berikut di file proxy.conf.json :

{
  "/api": {
    "target": "http://localhost:3000",
    "pathRewrite": {"^/api" : ""},
   "secure": false
 }
}

Dalam kasus Angular saya melayani dengan konfigurasi itu:

$ ng serve -o --proxy-config=proxy.conf.json

Saya lebih suka menggunakan proxy di perintah serve, tetapi Anda juga dapat meletakkan konfigurasi ini ke angular.json seperti ini:

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "src/proxy.conf.json"
    },

Lihat juga:

https://www.techiediaries.com/fix-cors-with-angular-cli-proxy-configuration/

https://webpack.js.org/configuration/dev-server/#devserverproxy

Juri Sinitson
sumber