Không có tiêu đề 'Kiểm soát truy cập-Cho phép-Xuất xứ' trên tài nguyên được yêu cầu. Do đó, nguồn gốc '' không được phép truy cập


135

Tôi đang sử dụng .htaccess để viết lại các url và tôi đã sử dụng thẻ cơ sở html để làm cho nó hoạt động.

Bây giờ, khi tôi cố gắng thực hiện một yêu cầu ajax, tôi gặp lỗi sau:

XMLHttpRequest không thể tải http://www.example.com/login.php. Không có tiêu đề 'Kiểm soát truy cập-Cho phép-Xuất xứ' trên tài nguyên được yêu cầu. Nguồn gốc ' http://example.com' do đó không được phép truy cập.


1
Không bao giờ ... nó đang hoạt động, tôi thậm chí không biết đâu là lỗi: S
Th3lmuu90

8
Tinh tế, http://wordicious.comlà một miền khác hơn http://www.wordicious.com/, do đó, lỗi. Btw, nếu nó đang hoạt động và tự quay trở lại, có lẽ bạn nên xóa câu hỏi.
acdcjunior

@acdcjunior Đó có vẻ là lỗi, đó là một quan sát sắc sảo về phía bạn. Nếu bạn đăng nó như là một câu trả lời tôi sẽ nâng cao nó.
Waleed Khan

5
Đó là một điều tốt câu hỏi đã không bị xóa, hoặc tôi sẽ không nhìn thấy nó ngày hôm nay!
đá

Câu trả lời:


170

Sử dụng addHeaderThay vì sử dụngsetHeader phương pháp,

response.addHeader("Access-Control-Allow-Origin", "*");

*ở dòng trên sẽ cho phép access to all domains.


Cho phép access to specific domain only :

response.addHeader("Access-Control-Allow-Origin", "http://www.example.com");

Kiểm tra này blog post.


4
nó đang hiển thị addheader không được xác định. Bạn có thể vui lòng giải thích nó?
Vaisakh Pc

9
Tôi đặt những dòng này ở đâu?
DaveWalley

14
Điều này nên được thêm vào đâu?
Alex

1
Bài đăng trên blog đó đang nói về Node.js và express. Không phải javascript phía khách hàng. bất cứ ai có thể xác nhận nếu điều này làm việc?
Sam Eaton

1
Tôi không nghĩ rằng cấu hình này chỉ có thể được thực hiện ở phía máy khách .. Vì vậy, để đặt nó ở đâu, nó sẽ nằm ở mã phía máy chủ (có lẽ là khi xây dựng phản hồi cho yêu cầu)
Chirag Ravindra

145

Tại sao lỗi được nêu ra:

Mã JavaScript được giới hạn bởi các chính sách cùng nguồn gốc , có nghĩa là, từ một trang tại www.example.com, bạn chỉ có thể thực hiện (AJAX) yêu cầu các dịch vụ nằm ở chính xác cùng một tên miền, trong trường hợp đó, chính xác www.example.com( không example.com - mà không www- hoặcwhatever.example.com ).

Trong trường hợp của bạn, mã Ajax của bạn đang cố gắng tiếp cận một dịch vụ http://wordicious.comtừ một trang nằm ở http://www.wordicious.com.

Mặc dù rất giống nhau, chúng không cùng tên miền. Và khi chúng không nằm trên cùng một miền, yêu cầu sẽ chỉ thành công nếu phản hồi của mục tiêu chứa Access-Control-Allow-Origintiêu đề trong đó.

Như trang / dịch vụ của bạn tại http://wordicious.com chưa bao giờ được định cấu hình để hiển thị tiêu đề như vậy, thông báo lỗi đó được hiển thị.

Giải pháp:

Như đã nói, nguồn gốc (nơi có trang JavaScript) và tên miền đích (nơi JavaScript đang cố gắng tiếp cận) phải chính xác như vậy.

Trường hợp của bạn có vẻ như một lỗi đánh máy. Có vẻ như http://wordicious.comhttp://www.wordicious.comthực sự là cùng một máy chủ / tên miền. Vì vậy, để khắc phục, hãy nhập mục tiêu và nguồn gốc như nhau: làm cho bạn các trang / dịch vụ yêu cầu mã Ajax thành http://www.wordicious.comkhônghttp://wordicious.com . (Có thể đặt URL mục tiêu tương đối, như '/login.php', không có tên miền).



Trên một lưu ý chung hơn:

Nếu vấn đề không phải là một lỗi đánh máy như câu hỏi này, thì giải pháp sẽ là thêm Access-Control-Allow-Origintên miền đích . Tất nhiên, để thêm nó, phụ thuộc vào máy chủ / ngôn ngữ đằng sau địa chỉ đó. Đôi khi một biến cấu hình trong công cụ sẽ thực hiện thủ thuật. Những lần khác, bạn sẽ phải tự thêm tiêu đề thông qua mã.


62

Đối với máy chủ .NET có thể định cấu hình này trong web.config như hiển thị bên dưới

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="your_clientside_websiteurl" />
     </customHeaders>
   </httpProtocol>
 </system.webServer>

Chẳng hạn, giả sử, nếu miền máy chủ là http://live.makemypublication.com và máy khách là http://www.makemypublication.com thì hãy định cấu hình trong web.config của máy chủ như dưới đây

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="http://www.makemypublication.com" />
     </customHeaders>
  </httpProtocol>
 </system.webServer>

Một giải pháp thậm chí tốt hơn. Cảm ơn
ANJYR - KODEXPRESSION

Cảm ơn rất nhiều. Bạn đã cứu cả ngày của tôi.
Prateek Gupta

Làm việc ngay cả sau 2 năm: p
Nhà phát triển xuất sắc

1
@SyedAliTaqi câu hỏi là php, đó là lý do tại sao câu trả lời bị đánh giá thấp. tuy nhiên nó cũng có tác dụng với tôi :)
Ahmad Th

22

Nếu bạn nhận được thông báo lỗi này từ trình duyệt:

Không có tiêu đề 'Kiểm soát truy cập-Cho phép-Xuất xứ' trên tài nguyên được yêu cầu. Do đó, nguồn gốc '' không được phép truy cập

khi bạn đang cố gắng thực hiện một yêu cầu POST / GET Ajax đến một máy chủ từ xa ngoài tầm kiểm soát của bạn, xin vui lòng quên cách khắc phục đơn giản này:

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

Những gì bạn thực sự cần làm, đặc biệt nếu bạn chỉ sử dụng JavaScript để thực hiện yêu cầu Ajax, là một proxy nội bộ lấy truy vấn của bạn và gửi nó đến máy chủ từ xa.

Đầu tiên trong JavaScript của bạn, hãy thực hiện một cuộc gọi Ajax đến máy chủ của riêng bạn, đại loại như:

$.ajax({
    url: yourserver.com/controller/proxy.php,
    async:false,
    type: "POST",
    dataType: "json",
    data: data,
    success: function (result) {
        JSON.parse(result);
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log(xhr);
    }
});

Sau đó, tạo một tệp PHP đơn giản có tên proxy.php để bọc dữ liệu POST của bạn và nối chúng vào máy chủ URL từ xa làm tham số. Tôi cho bạn một ví dụ về cách tôi bỏ qua vấn đề này với API tìm kiếm của Khách sạn Expedia:

if (isset($_POST)) {
  $apiKey = $_POST['apiKey'];
  $cid = $_POST['cid'];
  $minorRev = 99;

  $url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;

  echo json_encode(file_get_contents($url));
 }

Bằng cách làm:

 echo json_encode(file_get_contents($url));

Bạn chỉ đang thực hiện cùng một truy vấn nhưng về phía máy chủ và sau đó, nó sẽ hoạt động tốt.


@NizarBsb bạn bị điên bạn biết điều đó !!!!! : D, cảm ơn rất nhiều câu trả lời của bạn đã cứu mạng tôi
Flash

10

Bạn cần thêm phần này vào đầu trang php "login.php"

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

5
Chắc chắn không an toàn.
gọi lại

7

bạn phải đặt các khóa / giá trị tiêu đề trong đáp ứng phương thức tùy chọn. ví dụ: nếu bạn có tài nguyên tại http://mydomain.com/myresource thì, trong mã máy chủ của bạn, bạn viết

//response handler
void handleRequest(Request request, Response response) {
    if(request.method == "OPTIONS") {
       response.setHeader("Access-Control-Allow-Origin","http://clientDomain.com")
       response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
       response.setHeader("Access-Control-Allow-Headers", "Content-Type");
    }



}

3

Về cơ bản thay đổi phản hồi tiêu đề API bằng cách thêm các tham số bổ sung sau.

Kiểm soát truy cập-Cho phép-Thông tin xác thực: đúng

Kiểm soát truy cập-Cho phép-Xuất xứ: *

Nhưng đây không phải là giải pháp tốt khi nói đến bảo mật


3

Giải pháp thay thế là sử dụng proxy ngược chạy trên máy chủ 'nguồn' của bạn và chuyển tiếp đến máy chủ mục tiêu của bạn, chẳng hạn như Fiddler:

Liên kết tại đây: http://docs.telerik.com/fiddler/configure-fiddler/t task / usefiddlerasreverseproxy

Hoặc một proxy Reverse Apache ...


điều này có thể được thực hiện ở cấp cấu hình Apache hoặc Nginx cho một miền. ví dụ: nếu người dùng đang truy cập mysite.com (không có www) và XHR đang yêu cầu www.mysite.com, một lệnh htaccess hoặc httpd.conf có thể giải quyết vấn đề này không?
codecowboy

Chắc chắn, Ứng dụng Front-End của bạn sẽ hoạt động như một proxy ngược. ví dụ: đối với Apache, bạn phải cài đặt mod_proxy và định cấu hình quy tắc của mình bằng ProxyPassReverse ( httpd.apache.org/docs/civerse/mod/m ). Các tính năng tương tự dường như cũng có sẵn trên Nginx: wiki.nginx.org/LikeApache
hzrari

2

Thêm tệp này vào tệp PHP hoặc bộ điều khiển chính

header("Access-Control-Allow-Origin: http://localhost:9000");

để kết thúc - bạn cũng cầnheader("Access-Control-Allow-Credentials: true");
Adam

1

Đã giải quyết với mục dưới đây trong httpd.conf

#CORS Issue
Header set X-Content-Type-Options "nosniff"
Header always set Access-Control-Max-Age 1728000
Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT,PATCH"
Header always set Access-Control-Allow-Headers: "DNT,X-CustomHeader,Keep-Alive,Content-Type,Origin,Authentication,Authorization,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control"
Header always set Access-Control-Allow-Credentials true

#CORS REWRITE
RewriteEngine On                  
RewriteCond %{REQUEST_METHOD} OPTIONS 
#RewriteRule ^(.*)$ $1 [R=200,L]
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]]

Cách duy nhất hiệu quả với tôi trên Apache2, CentOS7, Larravel 5 và React
Shakiba Moshiri

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.