API Gateway CORS: tidak ada header 'Access-Control-Allow-Origin'

106

Meskipun CORS telah disiapkan melalui API Gateway dan Access-Control-Allow-Originheader telah disetel, saya masih menerima kesalahan berikut saat mencoba memanggil API dari AJAX dalam Chrome:

XMLHttpRequest tidak dapat memuat http://XXXXX.execute-api.us-west-2.amazonaws.com/beta/YYYYY . Tidak ada header 'Access-Control-Allow-Origin' yang ada di resource yang diminta. Oleh karena itu, asal 'null' tidak diizinkan mengakses. Responsnya memiliki kode status HTTP 403.

Saya mencoba MENDAPATKAN URL melalui Postman dan itu menunjukkan header di atas berhasil dilewatkan:

Header lolos

Dan dari jawaban OPTIONS:

Header respons

Bagaimana cara memanggil API saya dari browser tanpa kembali ke JSON-P?

Tyler
sumber
Apakah Anda sudah mengaturnya di S3? Jika ya, dapatkah Anda memasang Bucket Policy? Pastikan Anda memiliki metode dalam kebijakan Anda
iSkore
11
Tim API Gateway di sini ... Jika Anda menggunakan fitur 'Aktifkan CORS' di konsol, konfigurasinya harus benar. Tebakan terbaik saya adalah Anda tidak menggunakan jalur sumber daya yang benar di API Anda di JavaScript yang dijalankan browser. Jika Anda mencoba membuat panggilan API ke metode / sumber daya / tahapan yang tidak ada, Anda akan menerima 403 generik tanpa header CORS. Saya tidak melihat bagaimana browser bisa melewatkan header Access-Control-Allow-Origin jika Anda memanggil sumber daya yang tepat karena panggilan OPTIONS di Postman dengan jelas berisi semua header CORS yang benar.
jackko
1
@ RyanG-AWS klien tidak menandatangani permintaan karena API diautentikasi oleh sumber daya yang dipanggilnya menggunakan token khusus pengguna, jadi kredensial bukan merupakan faktor. Saya dapat memanggil API dengan mengunjungi URL langsung di browser dan saya mendapatkan respons yang sesuai.
Tyler
2
@makinbacon: Apakah Anda menemukan solusi untuk ini? Saya mengalami masalah yang sama di sini.
Nirmal
1
Metode dan panggung saya dibuat secara otomatis oleh Lambda. Saya mengaktifkan CORS setelah kejadian tersebut. Kesalahan yang sama seperti OP. Saya meniup barang-barang yang dibuat secara otomatis, membuat API dan metode baru, diterapkan ke tahap baru, dan itu berfungsi dengan baik.
melepuh

Jawaban:

125

Saya mendapatkan masalah yang sama. Saya telah menggunakan 10 jam untuk mencari tahu.

https://serverless.com/framework/docs/providers/aws/events/apigateway/

// handler.js

'use strict';

module.exports.hello = function(event, context, callback) {

const response = {
  statusCode: 200,
  headers: {
    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS 
  },
  body: JSON.stringify({ "message": "Hello World!" })
};

callback(null, response);
};
riseres
sumber
Memperbaiki masalah yang saya alami juga. Terima kasih atas jawaban Anda!
Eric Brown
Saya tidak menggunakan tanpa server, tetapi ini menyelesaikan masalah saya. Sepertinya Anda perlu meneruskan header tersebut dari sumber sebenarnya.
Costa
2
FYI, ada masalah dengan contoh yang disajikan di sini. Jika Anda memiliki "Access-Control-Allow-Credentials": true, Anda tidak dapat memiliki wildcard * untuk Access-Control-Allow-Origin. Aturan ini diberlakukan oleh browser. Lihat di sini dan di sini
Kevin
1
Ini tidak berfungsi, Sekali lagi menunjukkan kesalahan yang sama Bidang header permintaan akses-kontrol-izinkan-kredensial tidak diizinkan oleh Access-Control-Allow-Headers dalam respons preflight.
mitesh7172
1
Bagi siapa pun yang penasaran, berikut adalah dokumen resmi yang menyebutkan ini: docs.aws.amazon.com/apigateway/latest/developerguide/… > Untuk integrasi proxy Lambda atau HTTP, Anda masih dapat mengatur header respons> OPTIONS yang diperlukan di API Gateway. Namun, Anda harus mengandalkan> ujung belakang untuk mengembalikan header Access-Control-Allow-Origin karena> respons integrasi dinonaktifkan untuk integrasi proxy.
Leonid Usov
109

Jika ada orang lain yang masih mengalami masalah ini - saya dapat melacak akar penyebabnya di aplikasi saya.

Jika Anda menjalankan API-Gateway dengan Otorisasi khusus - API-Gateway akan mengirim kembali 401 atau 403 sebelum benar-benar mengenai server Anda. Secara default - API-Gateway TIDAK dikonfigurasikan untuk CORS saat mengembalikan 4xx dari pemberi otorisasi khusus.

Juga - jika Anda kebetulan mendapatkan kode status 0atau 1dari permintaan yang berjalan melalui API Gateway, ini mungkin masalah Anda.

Untuk memperbaiki - dalam konfigurasi API Gateway - buka "Gateway Responses", luaskan "Default 4XX" dan tambahkan header konfigurasi CORS di sana. yaitu

Access-Control-Allow-Origin: '*'

Pastikan untuk menerapkan ulang gateway Anda - dan voila!

Gabriel Doty
sumber
7
Aku cinta kamu. serius telah mengerjakan ini selama dua hari.
efong5
4
Bagi mereka yang ingin melakukan ini dengan AWS CLI, gunakan:aws apigateway update-gateway-response --rest-api-id "XXXXXXXXX" --response-type "DEFAULT_4XX" --patch-operations op="add",path="/responseParameters/gatewayresponse.header.Access-Control-Allow-Origin",value='"'"'*'"'"'
Will
1
Saya tidak menggunakan Pengotorisasi khusus dan masih membutuhkannya karena permintaan saya mengandung JSON yang buruk - terima kasih!
Force Hero
9
catatan untuk diri saya sendiri - jangan lupa untuk menerapkan API setelahnya :)
danieln
2
Aneh, ini berhasil untuk saya, tetapi saya tidak perlu menerapkan ulang. Saya memang mencoba menerapkan ulang sebelumnya. Tidak yakin mengapa itu berhasil untuk saya.
Michael
19

1) Saya perlu melakukan hal yang sama seperti @riseres dan beberapa perubahan lainnya. Ini adalah header tanggapan saya:

headers: {
            'Access-Control-Allow-Origin' : '*',
            'Access-Control-Allow-Headers':'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Credentials' : true,
            'Content-Type': 'application/json'
        }

2) Dan

Menurut dokumentasi ini:

http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

Saat Anda menggunakan proxy untuk fungsi lambda pada konfigurasi API Gateway, metode posting atau get tidak memiliki header tambahan, hanya opsinya saja. Anda harus melakukannya secara manual dalam respons (respons server atau lambda).

3) Dan

Selain itu, saya perlu menonaktifkan opsi 'API Key Diperlukan' dalam metode posting gateway API saya.

Carlos Alberto Schneider
sumber
5
Ya, menurut saya hal halus yang banyak dari kita lewatkan pada awalnya adalah setelah Anda mengonfigurasi integrasi API Gateway untuk fungsi Lambda dengan "Gunakan Integrasi Proxy Lambda", Anda harus melakukan apa yang Anda dan orang lain nyatakan dan memastikan tajuk ditambahkan secara terprogram dalam respons lambda Anda. Hal-hal auto-gen yang dibuat dengan "Mengaktifkan CORS" pada API Gateway dan itu membuat responder OPTIONS sangat bagus tetapi tidak membawa Anda ke sana jika Anda menyetel "Gunakan integrasi Proxy Lambda" dalam Permintaan Integrasi dalam API Pintu gerbang.
1
Ini berhasil untuk saya ... setelah membaca manual dengan benar: Penting Saat menerapkan petunjuk di atas ke metode APA PUN dalam integrasi proxy, semua header CORS yang berlaku tidak akan disetel. Sebagai gantinya, backend Anda harus mengembalikan header CORS yang berlaku, seperti Access-Control-Allow-Origin. docs.aws.amazon.com/apigateway/latest/developerguide/...
BennyHilarious
19

Jika Anda telah mencoba segala sesuatu tentang masalah ini tetapi tidak berhasil, Anda akan berakhir seperti yang saya lakukan. Ternyata, arah penyiapan CORS Amazon yang ada berfungsi dengan baik ... pastikan Anda ingat untuk menerapkan ulang ! Wizard pengeditan CORS, bahkan dengan semua tanda centang hijau kecilnya yang bagus, tidak membuat pembaruan langsung ke API Anda. Mungkin sudah jelas, tapi itu membuatku bingung selama setengah hari.

masukkan deskripsi gambar di sini

lase
sumber
2
Ini dia. Secara harfiah mengerjakan ini selama dua hari. Tidak yakin logika tidak setidaknya meminta penerapan ulang setelah Anda mengedit gateway.
Chris Christensen
@ChrisChristensen senang Anda mengetahuinya - selalu ada sesuatu yang sangat melegakan namun sangat mengalahkan tentang masalah seperti ini
lase
Ini adalah jawaban yang valid pada tahun 2020. Terima kasih
Rahul Khanna
1
RE-DEPLOY RE-DPLOY RE-DEPLOY
Surjith SM
12

Membuat sampel saya berfungsi: Saya baru saja memasukkan 'Access-Control-Allow-Origin': '*', di dalam header: {} di fungsi Lambda nodejs yang dihasilkan. Saya tidak membuat perubahan pada lapisan API yang dihasilkan Lambda.

Inilah NodeJS saya:

'use strict';
const doc = require('dynamodb-doc');
const dynamo = new doc.DynamoDB();
exports.handler = ( event, context, callback ) => {
    const done = ( err, res ) => callback( null, {
        statusCode: err ? '400' : '200',
        body: err ? err.message : JSON.stringify(res),
        headers:{ 'Access-Control-Allow-Origin' : '*' },
    });
    switch( event.httpMethod ) {
        ...
    }
};

Ini panggilan AJAX saya

$.ajax({
    url: 'https://x.execute-api.x-x-x.amazonaws.com/prod/fnXx?TableName=x',
    type: 'GET',
    beforeSend: function(){ $( '#loader' ).show();},
    success: function( res ) { alert( JSON.stringify(res) ); },
    error:function(e){ alert('Lambda returned error\n\n' + e.responseText); },
    complete:function(){ $('#loader').hide(); }
});
MannyC
sumber
Saya menemukan banyak dokumentasi Amazon yang kedaluwarsa, bahkan dengan fragmen jalur "../latest/ ..". Setelah membuang semuanya sekitar seminggu yang lalu, tombol CORS tiba-tiba dinyatakan berfungsi dengan benar. API membuat metode "APA SAJA" secara otomatis dan tombol CORS membuat metode "OPTIONS" secara otomatis - Saya tidak menambahkan apa pun ke API. "GET" di atas berfungsi dan saya telah menambahkan "POST" ajax yang juga berfungsi tanpa saya menyentuh API.
MannyC
Saya menghabiskan hampir dua jam mencoba mencari cara agar Access-Control-Allow-Origin ditambahkan ke respons metode menggunakan konsol AWS, tetapi ini juga satu-satunya hal yang berhasil bagi saya.
Shn_Android_Dev
8

Untuk Karyawan Google:

Inilah alasannya:

  • Permintaan sederhana, atau, GET/POST tanpa cookie tidak memicu preflight
  • Saat Anda mengonfigurasi CORS untuk sebuah jalur, API Gateway hanya akan membuat OPTIONSmetode untuk jalur tersebut, kemudian mengirim Allow-Originheader menggunakan respons tiruan saat pengguna memanggil OPTIONS, tetapi GET/ POSTtidak akan mendapatkanAllow-Origin otomatis
  • Jika Anda mencoba mengirim permintaan sederhana dengan mode CORS aktif, Anda akan mendapatkan kesalahan karena respons itu tidak memiliki Allow-Origin header
  • Anda dapat mematuhi praktik terbaik, permintaan sederhana tidak dimaksudkan untuk mengirim tanggapan kepada pengguna, mengirim otentikasi / cookie bersama dengan permintaan Anda untuk membuatnya "tidak sederhana" dan preflight akan memicu
  • Namun, Anda harus mengirim header CORS sendiri untuk permintaan berikut OPTIONS

Singkatnya:

  • Hanya tidak berbahaya yang OPTIONSakan dibuat oleh API Gateway secara otomatis
  • OPTIONShanya digunakan oleh browser sebagai tindakan pencegahan untuk memeriksa kemungkinan CORS di jalur
  • Apakah CORS diterima tergantung pada metode sebenarnya, misalnya GET/POST
  • Anda harus mengirim header yang sesuai secara manual dalam tanggapan Anda
theaws.blog
sumber
7

Saya baru saja menambahkan tajuk ke respons fungsi lambda saya dan itu bekerja seperti pesona

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hey it works'),
        headers:{ 'Access-Control-Allow-Origin' : '*' }
    };
    return response;
};
Vishal Shetty
sumber
4

Saya menemukan solusi sederhana di dalamnya

API Gateway> Pilih titik akhir API Anda> Pilih metode (dalam kasus saya itu adalah POST)

Sekarang ada TINDAKAN dropdown> Aktifkan CORS .. pilih itu.

Sekarang pilih TINDAKAN dropdown lagi> Terapkan API (terapkan kembali)

masukkan deskripsi gambar di sini

Berhasil!

Ravi Ram
sumber
Mengapa jawaban ini ditolak tetapi ada jawaban serupa lainnya di bawah ini?
Dinesh Kumar
Untuk
permintaan
3

Saya membuat milik saya berfungsi setelah saya menyadari bahwa lambda authoriser gagal dan untuk beberapa alasan yang tidak diketahui itu diterjemahkan menjadi kesalahan CORS. Perbaikan sederhana untuk penulis otorisasi saya (dan beberapa pengujian penulis otorisasi yang seharusnya saya tambahkan sejak awal) dan berhasil. Bagi saya, tindakan API Gateway 'Aktifkan CORS' diperlukan. Ini menambahkan semua tajuk dan pengaturan lain yang saya butuhkan di API saya.

RodP
sumber
dan terapkan kembali! :)
Robin C Samuel
3

Bagi saya, jawaban yang AKHIRNYA BEKERJA, adalah komentar dari James Shapiro dari jawaban Alex R (suara terbanyak kedua). Saya masuk ke masalah API Gateway ini pertama-tama, dengan mencoba mendapatkan halaman web statis yang dihosting di S3 untuk menggunakan lambda untuk memproses halaman hubungi kami dan mengirim email. Cukup dengan memeriksa [] Default 4XX memperbaiki pesan kesalahan.

masukkan deskripsi gambar di sini

Jason
sumber
Di mana Anda menemukan menu ini? Saya tidak melihatnya di mana pun.
Nick H
@NickH lihat gambar dari Ravi Ram. Di bawah "Actions", seharusnya ada item bernama "Enable CORS" dan ketika Anda memilihnya, menu akan muncul.
Jason
2

Setelah Mengubah Fungsi atau Kode Anda Ikuti dua langkah berikut.

Pertama Aktifkan CORS Kemudian Terapkan API setiap saat.

Ankit Kumar Rajpoot
sumber
Terima kasih untuk itu. Tidak melihat "Aktifkan CORS" di sumber daya. Membuat saya kehilangan akal.
Shlomi Bazel
2

Menerapkan kode setelah mengaktifkan CORS untuk keduanya POSTdan OPTIONSberhasil untuk saya.

Ziaur Rahman
sumber
1
Terima kasih atas kontribusi Anda, namun bisakah Anda menjelaskan mengapa hal itu bermanfaat bagi Anda? Saya mengundang Anda untuk membaca panduan ini untuk menyempurnakan jawaban Anda: "Bagaimana saya menulis jawaban yang baik" di sini: stackoverflow.com/help/how-to-answer
Guillaume Raymond
1

Saya sedang menjalankan aws-serverless-express, dan dalam kasus saya perlu mengeditsimple-proxy-api.yaml .

Sebelum CORS dikonfigurasi ke https://example.com, saya baru saja menukar nama situs saya dan menerapkan ulang melalui npm run setup, dan itu memperbarui lambda / stack saya yang ada.

#...
/:
#...
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
/{proxy+}:
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
James L.
sumber
1

Dalam kasus saya, karena saya menggunakan AWS_IAM sebagai metode Otorisasi untuk API Gateway, saya perlu memberikan izin peran IAM saya untuk mencapai titik akhir.

CamHart
sumber
2
Sobat, aku senang aku meninggalkan komentar ini. Hal ini terus terjadi pada saya: D.
CamHart
Saya suka menemukan solusi saya sendiri untuk masalah yang berulang di masa depan.
Zac Grierson
0

Akar penyebab lain dari masalah ini mungkin adalah perbedaan antara HTTP / 1.1 dan HTTP / 2.

Gejala: Beberapa pengguna, tidak semuanya, dilaporkan mendapatkan kesalahan CORS saat menggunakan Perangkat Lunak kami.

Masalah: The Access-Control-Allow-Originsundulan hilang kadang-kadang .

Konteks: Kami memiliki Lambda di tempat, yang didedikasikan untuk menangani OPTIONSpermintaan dan membalas dengan header CORS yang sesuai, seperti Access-Control-Allow-Originmencocokkan yang masuk daftar putih Origin.

Solusi: API Gateway tampaknya mengubah semua header menjadi huruf kecil untuk panggilan HTTP / 2, tetapi mempertahankan kapitalisasi untuk HTTP / 1.1. Ini menyebabkan akses event.headers.origingagal.

Periksa apakah Anda juga mengalami masalah ini:

Dengan asumsi API Anda terletak di https://api.example.com, dan front-end Anda di https://www.example.com. Menggunakan CURL, buat permintaan menggunakan HTTP / 2:

curl -v -X OPTIONS -H 'Origin: https://www.example.com' https://api.example.com

Output respon harus menyertakan tajuk:

< Access-Control-Allow-Origin: https://www.example.com

Ulangi langkah yang sama menggunakan HTTP / 1.1 (atau dengan Originheader huruf kecil ):

curl -v -X OPTIONS --http1.1 -H 'Origin: https://www.example.com' https://api.example.com

Jika Access-Control-Allow-Originheader hilang, Anda mungkin ingin memeriksa sensitivitas huruf saat membaca Originheader.

Michael Seibt
sumber
0

Selain komentar lain, sesuatu yang harus diperhatikan adalah status yang dikembalikan dari integrasi yang mendasarinya dan jika header Access-Control-Allow-Origin dikembalikan untuk status itu.

Melakukan hal 'Aktifkan CORS' hanya menyiapkan 200 status. Jika Anda memiliki endpoint lain, misalnya 4xx dan 5xx, Anda perlu menambahkan header sendiri.

Nigel Atkinson
sumber
-2

Dalam kasus saya, saya hanya salah menulis URL permintaan pengambilan. Aktif serverless.yml, Anda menyetel corske true:

register-downloadable-client:
    handler: fetch-downloadable-client-data/register.register
    events:
      - http:
          path: register-downloadable-client
          method: post
          integration: lambda
          cors: true
          stage: ${self:custom.stage}

dan kemudian pada penangan lambda Anda mengirim header, tetapi jika Anda membuat permintaan pengambilan yang salah di frontend, Anda tidak akan mendapatkan header tersebut pada respons dan Anda akan mendapatkan kesalahan ini. Jadi, periksa kembali URL permintaan Anda di bagian depan.

Ericson Willians
sumber
-3

Dengan Python Anda bisa melakukannya seperti pada kode di bawah ini:

{ "statusCode" : 200,
'headers': 
    {'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': "*"
     },
"body": json.dumps(
    {
    "temperature" : tempArray,
    "time": timeArray
    })
 }
Mukesh Arya
sumber