2016-12-17 23 views
9

Tôi đang cố gắng để thực hiện một php backend đơn giản để xử lý một hình thức liên lạc trong máy chủ khác, nhưng mặc dù thêm các tiêu đề thích hợp, nó giữ cho tôi được thông báo lỗi tương tự:XMLHttpRequest không thể tải tài nguyên

XMLHttpRequest cannot load https://php-contact-form-lual.herokuapp.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4000' is therefore not allowed access. The response had HTTP status code 404. 


Đây là yêu cầu ajax:

$.ajax({ 
    type: 'POST', 
    url: 'https://php-contact-form-lual.herokuapp.com/', 
    data: { 
      subject: 'subject', 
      to: 'receiver', 
      name: $('#name').val(), 
      email: $('#email').val(), 
      msg: $('#msg').val() 
      } 
    }) // then the callbacks 


và đây là php:

<?php 

    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { 
    // return only the headers and not the content 
    // only allow CORS if we're doing a POST - i.e. no saving for now. 
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') { 
    header('Access-Control-Allow-Origin: *'); 
    header('Access-Control-Allow-Headers: X-Requested-With'); 
    } 
    exit; 
} 

// handling the data  
$subject = $_POST['subject']; 
$to  = $_POST['to']; 
$name = $_POST['name']; 
$email = $_POST['email']; 
$msg  = $_POST['msg']; 
$msg  = "DE: " . $name . " (" . $email .")" . "\n\n" . $msg; 

mail($to, $subject, $msg); 

?> 

Lưu ý rằng các dòng mã trước khối "xử lý dữ liệu" được lấy từ this answer, tôi cũng đã thử với giải pháp đơn giản được trình bày trong phần đầu của cùng câu trả lời đó cũng ở nơi khác- và thậm chí thay thế dấu hoa thị với URL cụ thể, nhưng kết quả đã cùng :(

Bất kỳ trợ giúp sẽ được đánh giá cao :)


cập nhật: log trong những điều tôi đã cố gắng về phía máy chủ (từ cũ nhất đến hiện tại):

// Allow from any origin 
if (isset($_SERVER['HTTP_ORIGIN'])) { 
    header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); 
    header('Access-Control-Allow-Credentials: true'); 
    header('Access-Control-Max-Age: 86400'); // cache for 1 day 
} 

// Access-Control headers are received during OPTIONS requests 
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); 
} 

------------------------------------------ 

header("Access-Control-Allow-Origin: *"); 
header("Access-Control-Allow-Methods: POST, OPTIONS"); 

----------------------------------------- 

header("Access-Control-Allow-Origin: http://localhost:4000"); 
header("Access-Control-Allow-Methods: POST, OPTIONS"); 

----------------------------------------- 

header("Access-Control-Allow-Origin: http://localhost:4000"); 
header("Access-Control-Allow-Methods: POST, OPTIONS, GET"); 

----------------------------------------- 

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { 
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') { 
     header('Access-Control-Allow-Origin: *'); 
     header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers'); 
    } 
    exit; 
} 

------------------------------------------ 

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { 
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') { 
     header('Access-Control-Allow-Origin: *'); 
     header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers'); 
    } 
    exit; 
} 

// + sending headers though ajax 

------------------------------------------ 

header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers'); 

------------------------------------------- 

# created .htaccess file with this line: 
Header set Access-Control-Allow-Origin "*" 

------------------------------------------ 

header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Methods: POST, OPTIONS, GET'); 
header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers'); 

--------------------------------------------- 

header('Access-Control-Allow-Origin: http://localhost:4000'); 
header('Access-Control-Allow-Methods: POST, OPTIONS, GET'); 
header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers'); 

----------------------------------------------- 

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { 
    // return only the headers and not the content 
    // only allow CORS if we're doing a POST - i.e. no saving for now. 
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') { 
    header('Access-Control-Allow-Origin: *'); 
    header('Access-Control-Allow-Headers: X-Requested-With'); 
    } 
    exit; 
} 

-------------------------------------------------- 

header('Origin: http://localhost:4000'); 
header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); 


aditional thông tin

Tiêu đề yêu cầu

POST/HTTP/1.1 
Host: php-contact-form-lual.herokuapp.com 
Connection: keep-alive 
Content-Length: 88 
Accept: */* 
Origin: http://localhost:4000 
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Referer: http://localhost:4000/contacto/ 
Accept-Encoding: gzip, deflate, br 
Accept-Language: es,en-GB;q=0.8,en;q=0.6,de;q=0.4 

tiêu đề đáp ứng

HTTP/1.1 404 Not Found 
Connection: keep-alive 
Date: Sat, 17 Dec 2016 16:10:02 GMT 
Server: Apache 
Content-Length: 198 
Content-Type: text/html; charset=iso-8859-1 
Via: 1.1 vegur 
+0

Đây là truy vấn trùng lặp. hãy thử lấy trợ giúp từ đây http://stackoverflow.com/questions/20035101/no-access-control-allow-origin-header-is-present-on-the-requested-resource – Nadeem

+0

Cảm ơn @Nadeem, nhưng tôi đã đi qua câu hỏi đó và câu trả lời php không hoạt động và hầu hết các câu trả lời khác không giải quyết trực tiếp vấn đề, nhưng cung cấp giải pháp hoặc giải pháp của bên thứ ba với các chương trình phụ trợ không dựa trên php. Tôi thực sự muốn giải quyết nó cho php như đối với sở thích trí tuệ, tuy nhiên tôi đang xem xét mạnh mẽ để viết lại phụ trợ bằng ngôn ngữ khác. – Lual

+0

Điều kỳ lạ là các tiêu đề phản hồi không đề cập đến các tiêu đề truy cập của bạn. Heroku có lọc các tiêu đề bạn có thể quay lại không? – Chris

Trả lời

9

Tôi thấy rằng các máy chủ đang trở lại một 404 lỗi. Điều này cho thấy bạn không có PHP mã trên bên trong tập tin index.php dưới https://php-contact-form-lual.herokuapp.com/index.php.

Ngoài ra, xem xét liệu bạn có thực sự cần https. có máy chủ cũng chấp nhận đơn http yêu cầu, và nếu như vậy, tại sao bạn không cố gắng sử dụng nó mà không SSL?

Cuối cùng, bạn đã cố chuyển dữ liệu dưới dạng dữ liệu JSON bằng cách sử dụng jQuery $.ajaxdataType: "jsonp"JSON.stringify({}) một đối tượng cho $.ajax data?

1

Tôi đã đưa ra một trường hợp thử nghiệm cực kỳ đơn giản (giả sử một số máy chủ cục bộ, hoặc mac, v.v.)

Tập 1: site1/index.php

<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> 
<script> 
$ 
    .ajax({ 
     type: 'POST', 
     url: 'http://127.0.0.1:7772', 
     data: { 
      subject: 'foo bar 123', 
     } 
    }) 
    .done(function(data) { 
     alert(data); 
    }); 
</script> 
Site 1 - sending data 

Tập 2: site2/index.php

<?php 

header('Access-Control-Allow-Origin: *'); 

echo "You posted " . $_POST['subject']; 

Boot lên cả "máy chủ" địa phương, nếu bạn đang ở trên một mac, bạn có thể làm điều gì đó như:

cd ./site1/ 
php -S 127.0.0.1:7771 

cd ../site2/ 
php -S 127.0.0.1:7772 

Bây giờ, hãy đến 127.0.0.1:7771 và bạn sẽ thấy một cảnh báo nhỏ hiển thị nội dung của site2.

Bây giờ xóa bỏ dòng header vào trang web 2:

// header('Access-Control-Allow-Origin: *'); 

Và làm mới 127.0.0.1:7771 và bạn sẽ có lại một hình vuông với các lỗi của: No 'Access-Control-Allow-Origin' header is present on the requested resource

"Working" tiêu đề phản ứng/yêu cầu :

enter image description here

"không làm việc" phản ứng/yêu cầu tiêu đề:

enter image description here

Tôi nhấn mạnh rằng bạn không nên thêm header('Access-Control-Allow-Origin: *'); trong một địa điểm sản xuất. Nhưng bạn cần phải thu hẹp vấn đề và điều này là đủ để xảy ra lỗi/cấu hình sai xảy ra

+0

Downvote? Tôi đã đưa ra tất cả các công cụ mà OP cần để có thể trả lời câu hỏi của chính mình - mà thông tin mà anh ta/cô ấy cung cấp là điều mà hầu hết mọi người có thể làm. – Chris

+0

Xin chào @ Chris, cảm ơn câu trả lời của bạn, tôi đồng ý với bạn rằng điều này có thể đã làm rõ lỗi của tôi, vì thử nghiệm cục bộ sẽ khiến tôi nghĩ về các tùy chọn khác khác với phần đầu tiên của thông báo lỗi do trình duyệt đưa ra. – Lual

+0

PS: Tôi upvoted câu trả lời của bạn cho những điều cấp (Y) – Lual

4

Sự cố là mã trạng thái 404. Nó thậm chí không đạt đến mã bạn đang gõ.

  1. Bạn có

    $app->post('/', function() use($app) { 
        // This is the route you need to edit. 
    }); 
    
  2. Bạn có bất cứ "khi" hoặc điều kiện khác cho các tuyến đường? Nếu vậy, hãy xóa nó ngay bây giờ.

  3. Bạn phải có cấu hình cụ thể cho https? Tôi cũng lưu ý rằng bạn có các cài đặt khác nhau trên http (403) so với https (404), theo mặc định Heroku cung cấp cùng mã cho cả http và https trừ khi bạn đặt cấu hình cho Silex.

  4. Khi bạn làm việc đó (tức là không phải là 404), bạn sẽ cần trả về tiêu đề Access-Control-Allow-Origin cùng lúc với phản hồi (như bạn có trong một trong những ví dụ "những gì tôi đã thử". "exit" sau đó sẽ thực sự ngăn chặn các nội dung được trả lại mà không phải là hoàn toàn hữu ích (Bạn cần "thoát" sau khi tiêu đề chuyển hướng/vị trí, nhưng không phải ở đây)


ghi chú khác:..

  • Nếu bạn đang cố gắng tạo một chương trình phụ trợ PHP "đơn giản", tại sao lại chọn Heroku? Bạn không thực sự mã hóa PHP, nhưng mã hóa Symphony, Silex, Twig và tất cả các thư viện khác có nghĩa là bạn đang ở trong tài liệu và thư viện quá mức cần thiết.
  • Như bạn đang sử dụng Heroku, có một giao diện SwiftMailer (sẽ giúp bạn khai thác mail() an toàn!
+0

Cảm ơn nhận xét của bạn, tôi đã chọn Heroku vì độ tin cậy của nó. Câu đầu tiên của bạn thực sự mang lại cho tôi góc nhìn chính xác, tôi đã bỏ qua phần 404 của thông báo lỗi vì tôi giả định (sai) rằng trình duyệt đã cho tôi 404 đó vì các tiêu đề - và nó trở thành một cách khác xung quanh:/. Tôi đã upvoted câu trả lời của bạn và nếu @ChristosLytras không xuất bản bình luận của mình như là một câu trả lời, tôi sẽ chấp nhận của bạn (bình luận của ông cũng chỉ cho tôi 404 và được xuất bản trước khi câu trả lời của bạn). Một lần nữa, cảm ơn rất nhiều – Lual

+0

Vui vì bạn đã sắp xếp nó! Và đừng lo lắng về việc đánh dấu/không đánh dấu - những lời cảm ơn của bạn được đánh giá cao hơn nhiều vì tôi biết điều đó đã giúp ích. – Robbie

0

có tệp htaccess nào không?

Có?

Sau đó, bạn có thể thử cái này để kiểm tra không?

<IfModule mod_headers.c> 
SetEnvIfNoCase ORIGIN (.*) ORIGIN=$1 
Header always set Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, PATCH, DELETE" 
Header always set Access-Control-Allow-Origin "%{ORIGIN}e" 
Header always set Access-Control-Allow-Credentials "true" 
Header always set Access-Control-Allow-Headers "X-Accept-Charset,X-Accept,Content-Type" 
Header always set P3P "policyref='/w3c/p3p.xml', CP='NOI DSP COR NID CUR ADM DEV OUR BUS'" 
RewriteEngine On 
RewriteCond %{REQUEST_METHOD} OPTIONS 
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]  
</IfModule> 

Không?

Bạn có thể chuyển đổi htaccess này thành thẻ Tiêu đề php. Chuyển đổi mẫu tại đây How to convert my htaccess code to php header

Các vấn đề liên quan