Rumah  >  Soal Jawab  >  teks badan

Isu CORS dalam PHP: Maklum balas daripada permintaan pra-penerbangan tidak lulus. sumber yang dibenarkan

Jadi saya tahu terdapat banyak siaran CORS di luar sana dan saya hanya menambahnya tetapi saya tidak menemui sebarang jawapan yang boleh membantu saya. Jadi saya sedang membina aplikasi Angular 4 yang bergantung pada api php saya. Berfungsi secara tempatan tiada masalah, apabila saya membuangnya pada domain dengan api yang terletak di app.example.com 的应用程序和位于 api.example.com Saya tidak dapat melalui log masuk saya kerana saya mendapat ralat berikut:

XMLHttpRequest tidak boleh memuatkan http://api.example.com/Account/Login. Respons kepada permintaan prapenerbangan gagal semakan kawalan akses: Tidak Pengepala 'Access-Control-Allow-Origin' hadir dalam permintaan sumber. Jadi sumber "http://app.example.com" tidak dibenarkan akses.

Kod php saya kelihatan seperti ini:

$http_origin = $_SERVER['HTTP_ORIGIN'];

$allowed_domains = array(
    'http://example.com',
    'https://example.com',
    'http://app.example.com',
    'https://app.example.com',
    'http://www.example.com',
    'https://www.example.com'
);

if (in_array(strtolower($http_origin), $allowed_domains))
{  
    // header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Origin: $http_origin");
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Max-Age: 86400');
}

// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
        header("Access-Control-Allow-Headers: Authorization, Content-Type,Accept, Origin");
    exit(0);
}

Siaran Angular saya kelihatan seperti ini:

public login(login: Login): Observable<LoginResponse> {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    headers.append('Authorization', 'Basic ' + btoa(login.Username + ':' + login.Password));
    return  this.http.post(this.apiBaseUrl + '/Account/Login', "grant_type=client_credentials", { headers: headers })
        .map(response => {
            // code
        });
}

Jika saya menjalankan permintaan melalui Posmen (ini tidak menjejaskan CORS) saya mendapat:

{ "error": "invalid_client", "error_description": "Client credentials were not found in the headers or body" }

Saya cuba menetapkan asal kepada '*' hanya untuk menguji dan melihat sama ada ini adalah teras masalah, tetapi ia masih gagal dengan cara yang sama.

Edit Hanya mengemas kini dengan maklumat di bawah. Menukar kes dalam pengepala tidak mempunyai kesan, dan menarik kod keluar daripada pernyataan if tidak mempunyai kesan sama ada.

Saya menyahpepijat php dengan memberitahu apl langsung saya untuk pergi ke api tempatan dan php berfungsi seperti yang diharapkan. Ia menetapkan pengepala dan meletakkannya ke dalam setiap pernyataan if.

Edit Syot 2 Saya sangat memerlukan bantuan dan jika sesiapa mempunyai sebarang idea, saya amat menghargainya.

Edit Syot 3 Jika saya menetapkan semua bahan pengepala dalam .htaccess dan bukannya php ia membenarkan saya lulus. Namun, kini saya terperangkap dengan ralat yang disenaraikan di atas, iaitu ralat yang selalu saya perolehi apabila menggunakan Posmen, tetapi kini apabila menggunakan laman web sebenar.

{"error":"invalid_client","error_description":"在标头或正文中找不到客户端凭据"}

Tajuk respons saya kelihatan seperti ini

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:authorization, content-type, accept, origin
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:*

Setelah ia berfungsi, saya akan menukarnya daripada * kepada domain saya sahaja. Tetapi sekarang saya meninggalkannya sebagai *.

Tajuk saya atas permintaan.

P粉564192131P粉564192131387 hari yang lalu671

membalas semua(2)saya akan balas

  • P粉952365143

    P粉9523651432023-10-22 00:47:32

    Dalam kes serupa saya, bahagian hadapan Angular dan bahagian belakang Php membantu dengan kod di bawah. Mula-mula saya menghantar tajuk:

    header("Access-Control-Allow-Origin: http://localhost:4200");   
    header("Content-Type: application/json; charset=UTF-8");    
    header("Access-Control-Allow-Methods: POST, DELETE, OPTIONS");    
    header("Access-Control-Max-Age: 3600");    
    header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

    Selepas mereka saya boleh mengabaikan permintaan pilihan:

    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {    
       return 0;    
    }

    Pendekatan ini membantu saya mengendalikan kaedah permintaan terbenam "siaran" dan "padam" dalam Angular.

    balas
    0
  • P粉860370921

    P粉8603709212023-10-22 00:29:25

    Baiklah, saya mengalami masalah yang sama baru-baru ini dan saya menyelesaikan semuanya di bahagian belakang sahaja, tanpa bahan .htaccess.

    Apabila penyemak imbas menghantar permintaan silang pelayan, ia mula-mula menghantar permintaan OPTIONS untuk memastikan ia sah dan permintaan "sebenar" boleh dihantar. Permintaan "sebenar" dihantar apabila ia mendapat respons yang betul dan sah daripada OPTIONS.

    Kini, untuk kedua-dua permintaan pada bahagian belakang, anda perlu memastikan pengepala yang betul dikembalikan: jenis kandungan, benarkan asal, benarkan pengepala, dll...

    Pastikan bahawa dalam permintaan OPTIONS pada bahagian belakang, aplikasi mengembalikan pengepala dan mengembalikan respons dan bukannya meneruskan aliran penuh aplikasi.

    Dalam permintaan "sebenar" anda harus mengembalikan pengepala yang betul dan badan respons biasa.

    Contoh:

    //The Response object
        $res = $app->response;
    
        $res->headers->set('Content-Type', 'application/json');
        $res->headers->set('Access-Control-Allow-Origin', 'http://example.com');
        $res->headers->set('Access-Control-Allow-Credentials', 'true');
        $res->headers->set('Access-Control-Max-Age', '60');
        $res->headers->set('Access-Control-Allow-Headers', 'AccountKey,x-requested-with, Content-Type, origin, authorization, accept, client-security-token, host, date, cookie, cookie2');
        $res->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    
        if ( ! $req->isOptions()) {
            // this continues the normal flow of the app, and will return the proper body
            $this->next->call();
        } else {
            //stops the app, and sends the response
            return $res;
        }

    Perkara yang perlu diingat:

    • Jika anda menggunakan: "Access-Control-Allow-Credentials" = benar Pastikan "Access-Control-Allow-Origin" bukan "*", ia mesti ditetapkan kepada domain yang betul! (Banyak darah tumpah kat sini :/)

    • Tentukan pengepala benarkan yang anda akan dapat dalam "Kawalan-Akses-Benarkan-Pengepala" Jika anda tidak mentakrifkannya, permintaan akan gagal

    • Jika anda menggunakan "Kebenaran: Pembawa", maka "Kawalan-Kawalan-Benarkan-Kepala" juga harus mengandungi "Kebenaran", jika tidak, permintaan akan gagal

    balas
    0
  • Batalbalas