Asal tidak diizinkan oleh Access-Control-Allow-Origin

337

Saya sedang membuat Ajax.requestke server PHP jarak jauh dalam aplikasi Sencha Touch 2 (dibungkus dengan PhoneGap ).

Respons dari server adalah sebagai berikut:

XMLHttpRequest tidak dapat memuat http://nqatalog.negroesquisso.pt/login.php . Asal http://localhost:8888tidak diizinkan oleh Access-Control-Allow-Origin.

Bagaimana saya bisa memperbaiki masalah ini?

Ricardo
sumber
19
saat menggunakan jQuery, pengaturan dataType: 'jsonp',melakukan trik
amit
11
dengan cara itu bukan respons dari server. Lebih tepatnya kesalahan itu dikeluarkan di sisi klien.
matteo
2
Trik jsonp mungkin tidak bekerja lagi, fyi: stackoverflow.com/questions/12216208/...
drewww
7
Catatan, karena saya hanya menghabiskan setengah hari mengejar bug ini - Jika skrip sisi server gagal dengan kesalahan server internal, browser dapat menafsirkannya seolah-olah permintaan tidak diizinkan karena Access-Control-Allow-Origindan melaporkan ini sebagai kesalahan.
troelskn
1
@troelskn Anda baru saja menyelamatkan hidup saya. Saya sedang mencari-cari kesalahan CORS sejak 3 hari, dan itu hanya masalah konfigurasi Spring kecil yang menyebabkan 500, yang saya selesaikan dalam 5 menit setelah saya membaca komentar Anda dan saya benar-benar mencarinya. Terima kasih!
Alexis Dufrenoy

Jawaban:

378

Saya menulis artikel tentang masalah ini beberapa waktu lalu, Cross Domain AJAX .

Cara termudah untuk menangani ini jika Anda memiliki kontrol server yang merespons adalah dengan menambahkan header respons untuk:

Access-Control-Allow-Origin: *

Ini akan memungkinkan lintas-domain Ajax . Di PHP, Anda ingin memodifikasi respons seperti:

<?php header('Access-Control-Allow-Origin: *'); ?>

Anda cukup meletakkan Header set Access-Control-Allow-Origin *pengaturan di konfigurasi Apache atau file htaccess.

Perlu dicatat bahwa ini secara efektif menonaktifkan perlindungan CORS, yang sangat mungkin mengekspos pengguna Anda untuk menyerang . Jika Anda tidak tahu bahwa Anda secara khusus perlu menggunakan wildcard, Anda tidak boleh menggunakannya, dan sebaliknya Anda harus memasukkan daftar putih domain spesifik Anda:

<?php header('Access-Control-Allow-Origin: http://example.com') ?>
Matt Mombrea
sumber
4
Saya akan menghubungi penyedia server saya. Terima kasih
Ricardo
8
Apakah ada masalah keamanan dengan ini? Jawaban ini , misalnya, mengatakan "JavaScript dibatasi oleh" kebijakan asal yang sama "untuk alasan keamanan, Misalnya, skrip berbahaya tidak dapat menghubungi server jarak jauh dan mengirim data sensitif dari situs Anda."
JohnK
4
Luar biasa, saya hanya meletakkan ini di file server node.js saya: response.writeHead (200, {'Content-Type': contentType, 'Access-Control-Allow-Origin': '*'}); Dan itu berhasil. Terima kasih!
vbullinger
25
JohnK, ya, wildcard akan mengizinkan domain apa pun untuk mengirim permintaan ke host Anda. Saya sarankan mengganti tanda bintang dengan domain tertentu tempat Anda menjalankan skrip.
Nick
7
Sangat menarik bahwa Anda berpikir wildcard bahkan tidak disarankan @jfrej. Itu semua tergantung pada tujuan Anda. Misalnya, alasan kami menggunakan wildcard (dan mengeposkan jawaban ini) adalah karena kami membuat widget yang disematkan untuk digunakan oleh situs mana pun.
Matt Mombrea
63

Jika Anda tidak memiliki kontrol dari server, Anda bisa menambahkan argumen ini untuk peluncur Chrome Anda: --disable-web-security.

Perhatikan bahwa saya tidak akan menggunakan ini untuk "surfing web" normal. Untuk referensi, lihat posting ini: Nonaktifkan kebijakan asal yang sama di Chrome .

Jika Anda menggunakan Phonegap untuk benar-benar membangun aplikasi dan memuatnya ke perangkat, ini tidak akan menjadi masalah.

Travis Webb
sumber
Terima kasih. Tetapi aplikasi saya berjalan di perangkat seluler, saya tidak bisa meneruskan argumen ke pembungkus tampilan web saya.
Ricardo
Apakah Anda tidak menguji aplikasi Anda di browser terlebih dahulu? Bagaimana Anda melakukan debug?
Travis Webb
Ya saya men-debug di browser Chrome, tetapi aplikasi tidak akan berjalan di chrome. Itu akan berada di penyihir webview phonegap saya tidak bisa mengontrol.
Ricardo
4
baca jawabannya: Anda cukup menambahkan argumen ini ke peluncur Chrome Anda . Tidak ada pengaturan untuk ini di dalam Chrome
Travis Webb
2
Tentu saja tidak aman. OP meminta jalan keluar dari langkah-langkah keamanan.
Travis Webb
42

Jika Anda menggunakan Apache, tambahkan saja:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

dalam konfigurasi Anda. Ini akan menyebabkan semua tanggapan dari server web Anda dapat diakses dari situs lain mana pun di internet. Jika Anda hanya ingin mengizinkan layanan pada host Anda digunakan oleh server tertentu, Anda dapat menggantinya *dengan URL dari server asal:

Header set Access-Control-Allow-Origin: http://my.origin.host
Reza S
sumber
3
Dan jangan lupa memuat modul: header a2enmod
Walery Strauch
cara memuat modul: header a2enmod?
Ayesha
18

Jika Anda memiliki aplikasi ASP.NET / ASP.NET MVC , Anda dapat memasukkan header ini melalui file Web.config:

<system.webServer>
  ...

    <httpProtocol>
        <customHeaders>
            <!-- Enable Cross Domain AJAX calls -->
            <remove name="Access-Control-Allow-Origin" />
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>
C. Augusto Proiete
sumber
2
.NET MVC People, LIHAT di sini! Saya sebenarnya akan mengetikkan solusi dan menunjuk ke jawaban ini di blog saya sehingga orang dapat menemukannya lebih mudah. Tidak ada yang lebih buruk daripada mencoba melewati rintangan .NET / MVC dan menemukan apa pun selain solusi PHP / jQuery. Terima kasih @ Caio-Proiete
ottoflux
1
Kenapa ini tidak bekerja untuk saya? Saya menggunakan Chrome dan mencoba mengakses halaman keuangan Yahoo dari hosting lokal saya.
pemain baru
1
terima kasih itu berhasil untuk saya. Saya telah menambahkan dalam proyek kode sisi server (web.config).
Ethem
15

Ini adalah pertanyaan / jawaban pertama yang muncul untuk saya ketika mencoba memecahkan masalah yang sama menggunakan ASP.NET MVC sebagai sumber data saya. Saya menyadari ini tidak menyelesaikan pertanyaan PHP , tetapi cukup terkait untuk menjadi berharga.

Saya menggunakan ASP.NET MVC. The posting blog dari Greg Brant bekerja untuk saya. Pada akhirnya, Anda membuat atribut [HttpHeaderAttribute("Access-Control-Allow-Origin", "*")],, yang dapat Anda tambahkan ke tindakan pengontrol.

Sebagai contoh:

public class HttpHeaderAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public HttpHeaderAttribute(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AppendHeader(Name, Value);
        base.OnResultExecuted(filterContext);
    }
}

Dan kemudian menggunakannya dengan:

[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
    return Json( "Some public result" );
}
badMonkey
sumber
1
WebApi 2 memiliki ini dibangun sekarang. asp.net/web-api/overview/security/…
Matt Frear
10

Karena Matt Mombrea benar untuk sisi server, Anda mungkin mengalami masalah lain yaitu penolakan masuk daftar putih.

Anda harus mengkonfigurasi phonegap.plist Anda. (Saya menggunakan phonegap versi lama)

Untuk cordova, mungkin ada beberapa perubahan dalam penamaan dan direktori. Tetapi langkah-langkahnya sebagian besar harus sama.

Pertama pilih File yang mendukung> PhoneGap.plist

masukkan deskripsi gambar di sini

lalu di bawah "ExternalHosts"

Tambahkan entri, dengan nilai mungkin " http://nqatalog.negroesquisso.pt " Saya menggunakan * untuk tujuan debugging saja.

masukkan deskripsi gambar di sini

steve0hh
sumber
8

Ini mungkin berguna bagi siapa saja yang membutuhkan pengecualian untuk versi perujuk 'www' dan 'non-www':

 $referrer = $_SERVER['HTTP_REFERER'];
 $parts = parse_url($referrer);
 $domain = $parts['host'];

 if($domain == 'google.com')
 {
         header('Access-Control-Allow-Origin: http://google.com');
 }
 else if($domain == 'www.google.com')
 {
         header('Access-Control-Allow-Origin: http://www.google.com');
 }
Pembohong
sumber
Menunjuk saya ke arah yang benar dalam menyelesaikan kesalahan ACAO dengan biru. Sementara saya telah menambahkan nama host yang diizinkan dari googledrive. URL yang digunakan harus googledrive TIDAK googledrive
Kildareflare
7

Saya akan memberi Anda solusi sederhana untuk yang satu ini. Dalam kasus saya, saya tidak memiliki akses ke server. Dalam hal ini Anda dapat mengubah kebijakan keamanan di browser Google Chrome Anda untuk memungkinkan Access-Control-Allow-Origin. Ini sangat sederhana:

  1. Buat pintasan browser Chrome
  2. Klik kanan ikon pintasan -> Properti -> Pintasan -> Target

Tempel sederhana di "C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security.

Lokasi mungkin berbeda. Sekarang buka Chrome dengan mengklik pintasan itu.

Dibish
sumber
7

Saya sudah mengalami ini beberapa kali ketika bekerja dengan berbagai API. Seringkali perbaikan cepat adalah menambahkan "& callback =?" ke akhir sebuah string. Terkadang ampersand harus berupa kode karakter, dan terkadang "?": "? Callback =?" (lihat Penggunaan API Forecast.io dengan jQuery )

Francis Baptiste
sumber
6

Jika Anda sedang menulis Ekstensi Chrome dan mendapatkan error ini, maka akan yakin Anda telah menambahkan URL dasar API untuk Anda manifest.json's perizinan blok , misalnya:

"permissions": [
    "https://itunes.apple.com/"
]
itzg
sumber
6

Ini karena kebijakan asal yang sama . Lihat lebih lanjut di Mozilla Developer Network atau Wikipedia .

Pada dasarnya, dalam contoh Anda, Anda hanya perlu memuat http://nqatalog.negroesquisso.pt/login.phphalaman nqatalog.negroesquisso.pt, bukan localhost.

antyrat
sumber
1
Tapi saya perlu memuat layanan web dari perangkat seluler, saya akan memotong ini?
Ricardo
Anda perlu membuat beberapa perubahan di sisi server atau menggunakan JSONP en.wikipedia.org/wiki/JSONP
antyrat
6

jika Anda berada di bawah apache, tambahkan saja file .htaccess ke direktori Anda dengan konten ini:

Header set Access-Control-Allow-Origin: *

Header set Access-Control-Allow-Headers: content-type

Header set Access-Control-Allow-Methods: *
Vero O
sumber
5

Di Ruby on Rails , Anda bisa melakukannya di controller:

headers['Access-Control-Allow-Origin'] = '*'
fuzzyalej
sumber
controller apa yang Anda masukkan ini jika itu panggilan ajax? Bisakah saya melihat lebih banyak konteks kode?
rigdonmr
5

Anda dapat membuatnya berfungsi tanpa memodifikasi server dengan membuat broswer termasuk header Access-Control-Allow-Origin: *dalam respons HTTP OPTIONS '.

Di Chrome, gunakan ekstensi ini . Jika Anda menggunakan Mozilla, periksa jawaban ini .

forzagreen
sumber
5

Jika Anda mendapatkannya di Angular.js, maka pastikan Anda keluar dari nomor port Anda seperti ini:

var Project = $resource(
    'http://localhost\\:5648/api/...', {'a':'b'}, {
        update: { method: 'PUT' }
    }
);

Lihat di sini untuk info lebih lanjut.

Marius
sumber
4

Kami juga memiliki masalah yang sama dengan aplikasi phonegap yang diuji dalam chrome. Satu mesin windows yang kami gunakan di bawah file batch setiap hari sebelum Membuka Chrome. Ingat sebelum menjalankan ini, Anda perlu membersihkan semua instance chrome dari task manager atau Anda dapat memilih chrome untuk tidak berjalan di latar belakang.

BATCH: (gunakan cmd)

cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security
abksharma
sumber
1

Di Ruby Sinatra

response['Access-Control-Allow-Origin'] = '*' 

untuk semua orang atau

response['Access-Control-Allow-Origin'] = 'http://yourdomain.name' 
Mikhail Chuprynski
sumber
0

Ketika Anda menerima permintaan itu, Anda bisa

var origin = (req.headers.origin || "*");

daripada ketika Anda harus menanggapi pergi dengan sesuatu seperti itu:

res.writeHead(
    206,
    {
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Origin': origin,
    }
);
Alessandro Annini
sumber