it-swarm-vi.com

Tại sao JavaScript của tôi nhận được tiêu đề "Không 'Kiểm soát truy cập-Cho phép-Xuất xứ' xuất hiện trên tài nguyên được yêu cầu" khi Postman không?

Tôi đang cố gắng thực hiện ủy quyền bằng JavaScript bằng cách kết nối với RESTfulAPI được tích hợp trong Flask . Tuy nhiên, khi tôi thực hiện yêu cầu, tôi gặp lỗi sau:

XMLHttpRequest không thể tải http: // myApiUrl/login . 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 'null' không được phép truy cập.

Tôi biết rằng API hoặc tài nguyên từ xa phải đặt tiêu đề, nhưng tại sao nó hoạt động khi tôi thực hiện yêu cầu thông qua tiện ích mở rộng Chrome Người đưa thư ?

Đây là mã yêu cầu:

$.ajax({
    type: "POST",
    dataType: 'text',
    url: api,
    username: 'user',
    password: 'pass',
    crossDomain : true,
    xhrFields: {
        withCredentials: true
    }
})
    .done(function( data ) {
        console.log("done");
    })
    .fail( function(xhr, textStatus, errorThrown) {
        alert(xhr.responseText);
        alert(textStatus);
    });
2059
Mr Jedi

Nếu tôi hiểu đúng, bạn đang thực hiện XMLHttpRequest cho một tên miền khác với trang của bạn đang bật. Vì vậy, trình duyệt đang chặn nó vì nó thường cho phép một yêu cầu trong cùng một Origin vì lý do bảo mật. Bạn cần phải làm một cái gì đó khác nhau khi bạn muốn thực hiện một yêu cầu tên miền chéo. Hướng dẫn về cách đạt được điều đó là Sử dụng CORS.

Khi bạn đang sử dụng người đưa thư, họ không bị hạn chế bởi chính sách này. Được trích dẫn từ XMLHttpRequest:

Các trang web thông thường có thể sử dụng đối tượng XMLHttpRequest để gửi và nhận dữ liệu từ các máy chủ từ xa, nhưng chúng bị giới hạn bởi cùng một chính sách Origin. Phần mở rộng không quá giới hạn. Một tiện ích mở rộng có thể nói chuyện với các máy chủ từ xa bên ngoài Nguồn gốc của nó, miễn là lần đầu tiên nó yêu cầu quyền truy cập chéo gốc.

1124
MD. Sahib Bin Mahboob

Đây không phải là bản sửa lỗi cho sản xuất hoặc khi ứng dụng phải được hiển thị cho khách hàng, điều này chỉ hữu ích khi UI và Backend Development ở trên server khác nhau và trong sản xuất chúng thực sự nằm trên cùng một máy chủ. Ví dụ: Trong khi phát triển UI cho bất kỳ ứng dụng nào nếu có nhu cầu kiểm tra nó cục bộ trỏ nó đến máy chủ phụ trợ, trong kịch bản đó, đây là cách khắc phục hoàn hảo. Để sửa lỗi sản xuất, các tiêu đề CORS phải được thêm vào máy chủ phụ trợ để cho phép truy cập nguồn gốc chéo.

Cách dễ dàng là chỉ cần thêm tiện ích mở rộng trong google chrome để cho phép truy cập bằng CORS.

( https://chrom.google.com.vn/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=vi-US )

Chỉ cần bật tiện ích mở rộng này bất cứ khi nào bạn muốn cho phép truy cập vào không yêu cầu tiêu đề 'access-control-allow-Origin'.

Hoặc là 

Trong Windows, dán lệnh này trong cửa sổ run 

chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security

điều này sẽ mở một trình duyệt chrome mới cho phép truy cập vào yêu cầu tiêu đề không có 'access-control-allow-Origin'.

485
shruti

Nếu bạn có thể đối phó với JSON , thì hãy thử sử dụng JSONP (lưu ý P ở cuối) để nói giữa các tên miền:

$.ajax({
  type: "POST",
  dataType: 'jsonp',
  ...... etc ......

Tìm hiểu thêm về cách làm việc với JSONP tại đây :

Sự ra đời của JSONP - về cơ bản là một bản hack kịch bản chéo trang đồng thuận - đã mở ra cơ hội cho các bản mashup nội dung mạnh mẽ. Nhiều trang web nổi bật cung cấp dịch vụ JSONP, cho phép bạn truy cập vào nội dung của chúng thông qua API được xác định trước.

322
Gavin

Rất đơn giản để giải quyết nếu bạn đang sử dụng PHP . Chỉ cần thêm tập lệnh sau vào đầu trang PHP để xử lý yêu cầu:

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

Cảnh báo: Điều này có chứa vấn đề bảo mật cho tệp PHP của bạn mà kẻ tấn công có thể gọi nó. bạn phải sử dụng phiên và cookie để xác thực để ngăn chặn tệp/dịch vụ của bạn chống lại cuộc tấn công này. Dịch vụ của bạn dễ bị giả mạo yêu cầu chéo trang (CSRF).

Nếu bạn đang sử dụng Node-red bạn phải cho phép CORS trong tệp node-red/settings.js bằng cách bỏ bình luận các dòng sau:

// The following property can be used to configure cross-Origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
 Origin: "*",
 methods: "GET,PUT,POST,DELETE"
},
200
shady sherif

Tôi ước ai đó đã chia sẻ trang web này với tôi từ lâu http://cors.io/ nó sẽ tiết kiệm được rất nhiều thời gian so với việc xây dựng và dựa vào proxy của riêng tôi. Tuy nhiên, khi bạn chuyển sang sản xuất, có proxy của riêng bạn là đặt cược tốt nhất vì bạn vẫn kiểm soát tất cả các khía cạnh của dữ liệu của mình.

Tất cả những gì bạn cần:

https://cors.io/?http://HTTP_YOUR_LINK_HERE

168
yoshyosh

Nếu bạn đang sử dụng Node.js , hãy thử:

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

Thêm thông tin: CORS trên ExpressJS

67
Nguyen Tran

Có một vấn đề tên miền chéo sử dụng Ajax. Bạn phải chắc chắn rằng bạn đang truy cập các tệp của mình trên cùng một đường dẫn http:// mà không có www. (hoặc truy cập từ http://www. và đăng lên cùng một đường dẫn bao gồm www.) mà trình duyệt coi là một miền khác khi truy cập qua đường dẫn www. Là. Bạn đang đăng lên một tên miền khác và trình duyệt chặn luồng vì vấn đề Xuất xứ.

Nếu API không được đặt trên cùng một Máy chủ mà bạn đang yêu cầu, luồng bị chặn và bạn sẽ cần tìm một cách khác để giao tiếp với API.

63
Alin Razvan

Bởi vì 
$ .ajax ({loại: "POST" - Gọi T&UGRAVE;Y CHỌN 
$ .post ( - Gọi B&AGRAVE;I 

cả hai đều là Postman khác nhau gọi "POST" đúng cách nhưng khi chúng tôi gọi nó sẽ là "TÙY CHỌN"

Đối với dịch vụ web c # - webapi 

Vui lòng thêm mã sau vào tệp web.config trong thẻ <system.webServer>. Điều này sẽ làm việc

<httpProtocol>
    <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
</httpProtocol>

Vui lòng đảm bảo rằng bạn không thực hiện bất kỳ lỗi nào trong cuộc gọi ajax

jQuery

$.ajax({
    url: 'http://mysite.Microsoft.sample.xyz.com/api/mycall',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    type: "POST", /* or type:"GET" or type:"PUT" */
    dataType: "json",
    data: {
    },
    success: function (result) {
        console.log(result);    
    },
    error: function () {
        console.log("error");
    }
});

Vấn đề góc 4 xin vui lòng tham khảo: http://www.hubfly.com/blog/solutions/how-to-fix-angular-4-api-call-issues/

Lưu ý: Nếu bạn đang tìm kiếm nội dung tải xuống từ trang web của bên thứ ba thì điều này sẽ không giúp bạn. Bạn có thể thử mã sau đây nhưng không phải JavaScript.

System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.Microsoft.sample.xyz.com/api/mycall");
48
George Livingston

Hãy thử XDomain ,

Tóm tắt: Một thay thế/polyfill JavaScript thuần CORS. Không cần cấu hình máy chủ - chỉ cần thêm proxy.html trên tên miền bạn muốn liên lạc. Thư viện này sử dụng XHook để móc tất cả XHR , vì vậy XDomain nên hoạt động cùng với bất kỳ thư viện nào.

22
user3359786

Nếu bạn không muốn:

  1. Vô hiệu hóa bảo mật web trong Chrome
  2. Sử dụng JSONP
  3. Sử dụng trang web của bên thứ ba để định tuyến lại yêu cầu của bạn

và bạn chắc chắn rằng máy chủ của bạn đã bật CORS sau đó (kiểm tra CORS tại đây: http://www.test-cors.org/ )

Sau đó, bạn cần chuyển tham số Origin với yêu cầu của mình . Origin này PHẢI khớp với Origin mà trình duyệt của bạn gửi với yêu cầu của bạn.

Bạn có thể thấy nó hoạt động ở đây: http://www.wikinomad.com/app/detail/Campgrounds35391

Chức năng chỉnh sửa sẽ gửi yêu cầu GET & POST đến một tên miền khác để tìm nạp dữ liệu. Tôi đặt tham số Origin để giải quyết vấn đề . Phần cuối là công cụ mediaWiki.

tldr: Thêm tham số "Origin" vào các cuộc gọi của bạn phải là tham số Origin mà trình duyệt của bạn gửi (bạn không thể giả mạo tham số Origin)

11
Ganesh Krishnan

Tôi gặp vấn đề với điều này khi tôi sử dụng AngularJS để truy cập API của mình. Yêu cầu tương tự đã hoạt động trong SoapUI 5.0 và ColdFusion. Phương thức GET của tôi đã có tiêu đề Access-Control-Allow-Origin.

Tôi phát hiện ra rằng AngularJS đưa ra yêu cầu TÙY CHỌN "dùng thử" . Theo mặc định, ColdFusion tạo ra phương thức TÙY CHỌN, nhưng nó không có nhiều, các tiêu đề này cụ thể. Lỗi được tạo để đáp ứng với cuộc gọi TÙY CHỌN đó và không phải là cuộc gọi cố ý của tôi để NHẬN. Sau khi tôi thêm phương pháp TÙY CHỌN bên dưới vào API của mình, vấn đề đã được giải quyết.

<cffunction name="optionsMethod" access="remote" output="false" returntype="any" httpmethod="OPTIONS" description="Method to respond to AngularJS trial call">
    <cfheader name="Access-Control-Allow-Headers" value="Content-Type,x-requested-with,Authorization,Access-Control-Allow-Origin"> 
    <cfheader name="Access-Control-Allow-Methods" value="GET,OPTIONS">      
    <cfheader name="Access-Control-Allow-Origin" value="*">      
    <cfheader name="Access-Control-Max-Age" value="360">        
</cffunction>
8
Leonid Alzhin

Tôi có cấu hình sau, dẫn đến lỗi tương tự, khi yêu cầu phản hồi từ máy chủ.

Phía máy chủ:SparkJava -> cung cấp API REST
Phía máy khách:ExtJs6 -> cung cấp kết xuất Trình duyệt 

Về phía phía máy chủ tôi đã phải thêm điều này vào phản hồi: 

Spark.get("/someRestCallToSpark", (req, res) -> {
    res.header("Access-Control-Allow-Origin", "*"); //important, otherwise its not working 
    return "some text";
 });

Về phía phía khách hàng tôi đã phải thêm điều này vào yêu cầu: 

Ext.Ajax.request({
    url: "http://localhost:4567/someRestCallToSpark",
    useDefaultXhrHeader: false, //important, otherwise its not working
    success: function(response, opts) {console.log("success")},
    failure: function(response, opts) {console.log("failure")}
});
8
kiltek

Dựa trên câu trả lời của shruti , tôi đã tạo một lối tắt của trình duyệt Chrome với các đối số cần thiết:  enter image description here  enter image description here

8
Mohammad AlBanna

https://github.com/Rob--W/cors-anywhere/ cung cấp mã (Node.js) mà bạn có thể sử dụng để thiết lập và chạy proxy CORS của riêng mình. Nó đã tích cực duy trì và cung cấp một số tính năng để kiểm soát hành vi proxy ngoài việc gửi các tiêu đề phản hồi Access-Control-* chính xác.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS có chi tiết để giải thích cách trình duyệt xử lý các yêu cầu chéo gốc mà ứng dụng web phía khách tạo ra từ JavaScript và bạn phải làm gì cấu hình gửi bởi máy chủ yêu cầu được thực hiện, nếu bạn có thể.

Trong trường hợp một trang web bạn cần đưa ra yêu cầu và nhận được phản hồi từ việc không trả lại tiêu đề phản hồi Access-Control-Allow-Origin, các trình duyệt sẽ luôn sẽ chặn các yêu cầu Xuất xứ chéo được thực hiện trực tiếp bởi phía khách hàng của bạn Mã JavaScript từ làm việc. Và vì vậy, nếu trang web không phải là trang mà bạn kiểm soát và có thể định cấu hình hành vi, điều duy nhất will hoạt động trong trường hợp đó là ủy quyền cho các yêu cầu, thông qua proxy của chính bạn, bạn tự chạy hoặc thông qua proxy mở.

Như đã đề cập trong các bình luận khác ở đây, có những lý do chính đáng cho việc không tin tưởng một proxy mở với các yêu cầu của bạn. Điều đó nói rằng, nếu bạn biết những gì bạn đang làm và bạn quyết định một proxy mở hoạt động cho nhu cầu của bạn, https://cors-anywhere.herokuapp.com/ là một thứ đáng tin cậy có sẵn, được duy trì tích cực và chạy một phiên bản của https://github.com/Rob--W/cors-anywhere/ code.

Cũng như các proxy mở khác được đề cập ở đây (một vài trong số đó ít nhất dường như không còn tồn tại nữa), cách thức hoạt động là thay vì mã khách hàng của bạn gửi yêu cầu trực tiếp đến, ví dụ: http://foo.com bạn gửi nó đến https://cors-anywhere.herokuapp.com/http://foo.com và proxy thêm các tiêu đề Access-Control-* cần thiết vào phản hồi mà trình duyệt nhìn thấy.

7
sideshowbarker

Bạn có thể bỏ qua vấn đề bằng cách sử dụng YQL để ủy quyền yêu cầu thông qua các máy chủ của Yahoo. Nó chỉ là một vài dòng mã:

var yql_url = 'https://query.yahooapis.com/v1/public/yql';
var url = 'your api url';

$.ajax({
    'url': yql_url,
    'data': {
        'q': 'SELECT * FROM json WHERE url="'+url+'"',
        'format': 'json',
        'jsonCompat': 'new',
    },
    'dataType': 'jsonp',
    'success': function(response) {
        console.log(response);
    },
});

Đây là liên kết với lời giải thích: https://vverma.net/fetch-any-json-USE-jsonp-and-yql.html

7
camnesia

Nếu bạn đang sử dụng Entity Framework , có vẻ như lỗi này đôi khi sẽ bị ném ngay cả khi bạn đã bật CORS. Tôi đã tìm ra rằng lỗi xảy ra do thiếu quyết toán truy vấn. Tôi hy vọng điều này sẽ giúp những người khác trong tình huống tương tự.

Đoạn mã sau có thể đưa ra lỗi XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource.:

using (DBContext db = new DBContext())
{
    return db.Customers.Select(x => new
    {
        Name = x.Name,
        CustomerId = x.CustomerId,
    });
}

Để khắc phục, một cuộc gọi quyết toán như .ToList() hoặc .FirstOrDefault() ở cuối truy vấn là bắt buộc, như vậy:

using (DBContext db = new DBContext())
{
    return db.Customers.Select(x => new
    {
        Name = x.Name,
        CustomerId = x.CustomerId,
    }).ToList();
}
5
Loyalar

Trong trường hợp của tôi, tôi đã sử dụng ứng dụng JAX7 JEE7 và các thủ thuật sau đây hoạt động hoàn hảo với tôi:

@GET
    @Path("{id}")
    public Response getEventData(@PathParam("id") String id) throws FileNotFoundException {
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("/eventdata/" + id + ".json");
        JsonReader jsonReader = Json.createReader(inputStream);
        return Response.ok(jsonReader.readObject()).header("Access-Control-Allow-Origin", "*").build();
    }
5
Bhuwan Gautam

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

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '…' is therefore not allowed access

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

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

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

Đầu tiên trong mã 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.

Trả lời được sao chép và dán từ NizarBsb

4
Flash

Tôi đã có thể giải quyết thành công (trong trường hợp của tôi cho các phông chữ) bằng cách sử dụng htaccess nhưng rõ ràng, OP đang yêu cầu một chút khác biệt. Nhưng bạn có thể sử dụng mẫu FileMatch và thêm bất kỳ loại tiện ích mở rộng nào để nó không bị lỗi cros.

<IfModule mod_headers.c>
  <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css)$">
    Header set Access-Control-Allow-Origin "*"
  </FilesMatch>
</IfModule>

https://httpd.Apache.org/docs/2.4/mod/core.html#filesmatch

4
Danish

Đối với API GoLang:

Trước tiên, bạn có thể xem MDN CORS Doc để biết CORS là gì. Theo như tôi biết, CORS là về việc có cho phép Origin Of Request truy cập Tài nguyên máy chủ hay không.

Và bạn có thể hạn chế yêu cầu nào Origin có thể truy cập máy chủ bằng cách đặt Access-Control-Allow-Origin tại Header của Phản hồi máy chủ.

Ví dụ: Đặt tiêu đề sau trong Phản hồi máy chủ có nghĩa là chỉ yêu cầu được gửi từ http://foo.example mới có thể truy cập máy chủ của bạn:

Access-Control-Allow-Origin: http://foo.example

và sau đây cho phép yêu cầu được gửi từ bất kỳ Xuất xứ (hoặc tên miền):

Access-Control-Allow-Origin: *

Và như tôi biết trong thông báo lỗi, requested resource có nghĩa là tài nguyên của máy chủ, vì vậy No 'Access-Control-Allow-Origin' header is present on the requested resource. có nghĩa là bạn không đặt tiêu đề Access-Control-Allow-Origin trong Phản hồi máy chủ của mình hoặc có thể bạn đã đặt nhưng danh sách Yêu cầu không được liệt kê trong Access-Control-Allow-Origin truy cập:

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 'null' không được phép truy cập.

Trong GoLang, tôi sử dụng gói gorilla/mux để xây dựng máy chủ API tại localhost:9091 và tôi cho phép CORS bằng cách thêm "Access-Control-Allow-Origin", "*" vào tiêu đề phản hồi:

func main() { // API Server Code
    router := mux.NewRouter()
    // API route is /people,
    //Methods("GET", "OPTIONS") means it support GET, OPTIONS
    router.HandleFunc("/people", GetPeople).Methods("GET", "OPTIONS")
    log.Fatal(http.ListenAndServe(":9091", router))
}

// Method of '/people' route
func GetPeople(w http.ResponseWriter, r *http.Request) {

    // Allow CORS by setting * in sever response
    w.Header().Set("Access-Control-Allow-Origin", "*")

    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    json.NewEncoder(w).Encode("OKOK")
}

Và tôi sử dụng JavaScript trong ứng dụng khách, tại localhost:9092, yêu cầu của Chrome có thể nhận được "OKOK" từ Máy chủ localhost:9091.

function GetPeople() {
    try {
        var xhttp = new XMLHttpRequest();
        xhttp.open("GET", "http://localhost:9091/people", false);
        xhttp.setRequestHeader("Content-type", "text/html");
        xhttp.send();
        var response = JSON.parse(xhttp.response);
        alert(xhttp.response);
    }
    catch (error) {
        alert(error.message);
    }
}

Ngoài ra, bạn có thể kiểm tra tiêu đề yêu cầu/phản hồi của mình bằng các công cụ như Fiddler.

4
yu yang Jian

Câu hỏi phổ biến - Một điều khác cần xem xét nếu bạn đã đọc đến đây và không có gì khác giúp được. Nếu bạn có CDN như Akamai, Limelight hoặc tương tự, bạn có thể muốn kiểm tra khóa bộ đệm bạn có cho URI của tài nguyên. Nếu nó không bao gồm giá trị tiêu đề Origin, bạn có thể trả về một phản hồi được lưu trong bộ nhớ cache khi được yêu cầu từ một Origin khác. Chúng tôi chỉ dành nửa ngày để gỡ lỗi này. Cấu hình CDN đã được cập nhật để chỉ bao gồm giá trị Origin cho một vài tên miền được chọn là của chúng tôi và đặt nó thành null cho tất cả các tên miền khác. Điều này dường như hoạt động và cho phép các trình duyệt từ các miền đã biết của chúng tôi xem tài nguyên của chúng tôi. Chắc chắn tất cả các câu trả lời khác là điều kiện tiên quyết để đến đây nhưng nếu CDN là bước nhảy đầu tiên từ trình duyệt của bạn thì đây là điều cần xem xét. 

Trong trường hợp của chúng tôi, chúng tôi có thể thấy một số yêu cầu gửi đến dịch vụ của chúng tôi nhưng gần như không phải là khối lượng mà trang web đang gửi. Điều đó chỉ chúng tôi đến CDN. Chúng tôi có thể quay lại và thấy yêu cầu ban đầu được cung cấp từ yêu cầu trực tiếp, không phải là một phần của cuộc gọi trình duyệt AJAX và tiêu đề phản hồi Access-Control-Allow-Origin không được bao gồm. Rõ ràng CDN lưu trữ giá trị này. Cấu hình CDN của Akamai Tweak để xem xét giá trị tiêu đề yêu cầu Origin như một phần của trận đấu dường như đã làm cho nó hoạt động với chúng tôi.

4
4
Jared

Rất nhiều lần điều này xảy ra với tôi từ javascript đến php api của tôi, bởi vì một trong một vài lý do. Tôi quên đặt <?php header('Access-Control-Allow-Origin: *'); ? là một. Điều này rất hữu ích cho truy cập tên miền phụ. Một lý do khác là bởi vì trong yêu cầu ajax của jQuery tôi đang chỉ định một DataType cụ thể và trả về một DataType khác, do đó nó sẽ gây ra lỗi. 

Lý do cuối cùng và nổi bật nhất cho lỗi này là có lỗi phân tích cú pháp trên trang bạn đang yêu cầu. Nếu bạn nhấn url trang đó trong trình duyệt của bạn nhiều khả năng bạn sẽ thấy lỗi phân tích cú pháp và bạn sẽ có một số dòng để giải quyết vấn đề. 

Tôi hi vọng điêu nay se giup được ai đo. Mỗi lần tôi phải mất một thời gian để gỡ lỗi này và tôi ước mình có một danh sách kiểm tra những thứ cần xác minh.

3
Garrett Tacoronte

Trong yêu cầu jsonp, bạn nên bắt "jsonpCallback" và gửi lại cho anh ta.

$.ajax({
      url: lnk,
      type: 'GET',
      crossDomain: true,
      dataType: 'jsonp',
      success: function (ip) { console.log(ip.ip); },
      error: function (err) { console.log(err) }
});

Về phía phụ trợ (nếu bạn sử dụng như PHP phụ trợ)

echo $_GET['callback'].'({"ip":"192.168.1.1"})';

Trong trường hợp này, phản ứng phụ trợ có vẻ như 

jQuery331009526199802841284_1533646326884 ({"ip": "192.168.1.1"})

nhưng bạn có thể đặt "jsonpCallback" theo cách thủ công ở lối vào và bắt anh ta ở phía phụ trợ

$.ajax({
      url: lnk,
      type: 'GET',
      crossDomain: true,
      dataType: 'jsonp',
      jsonpCallback: 'get_ip',
      success: function (ip) { console.log(ip.ip); },
      error: function (err) { console.log(err) }
});

Trong trường hợp này, phản ứng phụ trợ có vẻ như 

get_ip ({"ip": "192.168.1.1"})

2
Alexey Kolotsey

Trên trang web của tôi (dựa trên .NET) Tôi vừa thêm điều này:

<system.webServer>
 <httpProtocol>  
    <customHeaders>  
     <add name="Access-Control-Allow-Origin" value="*" />  
     <add name="Access-Control-Allow-Headers" value="Content-Type" />  
     <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />  
    </customHeaders>  
  </httpProtocol>         
</system.webServer>

Cảm ơn rất nhiều đến cái này video.

2
FrenkyB

trong trường hợp bạn muốn sửa lỗi này trên phần phụ trợ (trong Flask), thay vì ở mặt trước, tôi hoàn toàn muốn giới thiệu gói python Flask CORS. Bình hoa

Với một dòng đơn giản trong ứng dụng của bạn, bạn có thể tự động chèn tiêu chuẩn cho phép mọi tiêu đề Xuất xứ hoặc tùy chỉnh nó theo yêu cầu.

2
Ben Watts

Để hoàn thiện, Apache cho phép cors:

Header set Access-Control-Allow-Origin "http://www.allowonlyfromthisurl.com"
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header set Access-Control-Max-Age "1000"
Header set Access-Control-Allow-Headers "x-requested-with, Content-Type, Accept-Encoding, Accept-Language, Cookie, Referer"
2
zak

CORS là dành cho bạn.

CORS là "Chia sẻ tài nguyên nguồn gốc chéo" và là một cách để gửi yêu cầu tên miền chéo. Bây giờ, cả XMLHttpRequest2 và Fetch API đều hỗ trợ CORS.

Nhưng nó có giới hạn của nó. Máy chủ cần xác nhận cụ thể Kiểm soát truy cập-Cho phép-Xuất xứ và không thể đặt thành '*'.

Và nếu bạn muốn bất kỳ Origin nào có thể gửi yêu cầu cho bạn, bạn cần JSONP (cũng cần đặt Access-Control-Allow-Origin, nhưng có thể là '*').

Đối với nhiều cách yêu cầu nếu bạn không biết chọn gì, tôi nghĩ bạn cần một thành phần đầy đủ chức năng để làm điều đó. Hãy để tôi giới thiệu một thành phần đơn giản catta


Nếu bạn đang sử dụng trình duyệt hiện đại (> Internet Explorer9, Chrome, Firefox, Edge, v.v.), bạn nên sử dụng một thành phần đơn giản nhưng đẹp, https://github.com/Joker-Jelly/catta. Nó không có phụ thuộc, nhỏ hơn 3 KB và hỗ trợ Fetch, Ajax và JSONP với cùng các tùy chọn và cú pháp đơn giản.

catta('./data/simple.json').then(function (res) {
  console.log(res);
});

Nó cũng hỗ trợ tất cả các cách để nhập vào dự án của bạn, như mô-đun ES6, CommonJS và thậm chí <script> trong HTML.

2
Jelly

Hầu hết các câu trả lời này cho người dùng biết cách thêm tiêu đề CORS vào máy chủ mà họ kiểm soát.

Tuy nhiên, nếu bạn cần dữ liệu từ máy chủ mà bạn không kiểm soát trong trang web, một giải pháp là tạo thẻ script trên trang của bạn, đặt thuộc tính src thành điểm cuối api không có tiêu đề CORS, sau đó tải dữ liệu đó lên trang:

window.handleData = function(data) {
  console.log(data)
};

var script = document.createElement('script');
script.setAttribute('src','https://some.api/without/cors/headers.com&callback=handleData');
document.body.appendChild(script);
2
duhaime

Tôi đã gặp lỗi này với $http.get trong Angular. Tôi cần sử dụng$http.jsonpthay vào đó.

2
Travis Heeter

Có thể nó hơi phức tạp một chút nhưng bạn có thể sử dụng máy chủ web để định tuyến yêu cầu . Với nodejs bạn không gặp phải vấn đề này. Tôi không phải là một chuyên gia trong nút js. Vì vậy, tôi không biết nếu đây là mã sạch. 

Nhưng điều này làm việc cho tôi

Đây là một ví dụ nhỏ:

NODE JS

var rp = require('request-promise');
var express = require('express'),
    app = express(),
    port = process.env.PORT || 3000;
var options = {
    method: 'POST',
    uri: 'http://api.posttestserver.com/post',
    body: {
        some: 'payload'
    },
    json: true // Automatically stringifies the body to JSON
};
app.get('/', function (req, res) {
        rp(options)
        .then(function (parsedBody) {
            res.send(parsedBody)
        })
        .catch(function (err) {
            res.send(err)
        });
});
app.listen(port);

JS

axios.get("http://localhost:3000/").then((res)=>{
    console.log('================res====================');
    console.log(res);
    console.log('====================================');
})
1
KT Works

Nếu máy chủ của bạn là Ứng dụng khởi động mùa xuân thì vui lòng thêm chú thích này vào bộ điều khiển còn lại của bạn ở trên cùng - @CrossOrigin

Nó nên hoạt động ngay bây giờ. Cảm ơn

1
Maiden

Đối với máy chủ Ruby on Rails trong application_controller.rb, hãy thêm cái này:

after_action :cors_set_access_control_headers

def cors_set_access_control_headers
  headers['Access-Control-Allow-Origin'] = '*'
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  headers['Access-Control-Allow-Headers'] = '*'
end
1
张健健

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 ' https://sx.xyz.com ' do đó không được phép truy cập.

Tôi cũng đã gặp phải một vấn đề tương tự với Trao đổi dữ liệu tên miền chéo trong phản hồi Ajax khi lỗi không xác định . Nhưng phản hồi trong tiêu đề là Mã trạng thái: 200 OK

Failed to load https://www.Domain.in/index.php?route=api/synchronization/checkapikey:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://sx.xyz.in' is therefore not allowed access.

Giải pháp khắc phục: Trong trường hợp của tôi, đó là gọi hàm checkapikey () qua Ajax đến một miền khác và nhận phản hồi với dữ liệu Cuộc gọi đã được thực hiện:

if (($this->request->server['REQUEST_METHOD'] == 'POST') && isset($this->request->server['HTTP_Origin'])) {

        $this->response->addHeader('Access-Control-Allow-Origin: ' . $this->request->server['HTTP_Origin']);
        $this->response->addHeader('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
        $this->response->addHeader('Access-Control-Max-Age: 1000');
        $this->response->addHeader('Access-Control-Allow-Credentials: true');
        $this->response->addHeader('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

        $headers = getallheaders();
...
}
1
Nishanth ॐ

Giải pháp này chắc chắn sẽ làm việc cho bạn. Thêm xử lý tin nhắn tùy chỉnh

public class CustomHeaderHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
        var referrer = request.Headers.Referrer;
        if (referrer != null && !response.Headers.Contains("Access-Control-Allow-Origin"))
        {
            response.Headers.Add("Access-Control-Allow-Origin", referrer.Scheme + "://" + referrer.Authority);
        }
        return response;
    }
}

Đăng ký trong webapiconfig.cs.

config.MessageHandlers.Add (new CustomHeaderHandler ());

Và nếu bạn đang sử dụng SignalR thì hãy thêm mã này vào tệp globle.asax.cs

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            var referrer = Request.UrlReferrer;
            if (Context.Request.Path.Contains("signalr/") && referrer != null)
            {
                Context.Response.AppendHeader("Access-Control-Allow-Origin", referrer.Scheme + "://" + referrer.Authority);
            }
        }
1
Ujjwal

Đối với Opera (nó hoạt động giống như Chrome), tôi đã khởi động trình duyệt bằng lệnh này:

opera --user-data-dir="~/Downloads/opera-session" --disable-web-security

Vấn đề đã được giải quyết! Bây giờ tôi có thể làm việc trên một tệp HTML cục bộ (trên ổ đĩa cứng của mình) và gọi các yêu cầu Ajax đến nguồn gốc từ xa trong cùng một tệp.

Lưu ý 1 : Bạn có thể cung cấp bất kỳ thư mục nào trong thư mục chính của mình dưới dạng --user-data-dir.

Lưu ý 2 : Đã thử nghiệm trên Debian 8 (Jessie)/Opera 39

 Here is a screenshot

Khi bạn bắt đầu bình thường (không có các tham số ở trên), cùng một yêu cầu rơi vào khối mã lỗi.

0
csonuryilmaz

Có lẽ bạn có thể sao chép tài nguyên từ máy chủ sản xuất sang máy chủ phát triển Và có URL tới tài nguyên để điều chỉnh động. Theo cách đó, bạn sẽ luôn luôn đọc từ cùng một Nguồn gốc, loại bỏ ngoại lệ Xuất xứ chéo.

0
bachstein

Trong trường hợp của tôi, tôi đang sử dụng dịch vụ khởi động mùa xuân làm dịch vụ, bạn có thể thêm sử dụng chú thích nguồn gốc chéo vào hoạt động có trách nhiệm.

@CrossOrigin(origins = "http://localhost:4200")
@RequestMapping(value = "getFoo", method = RequestMethod.GET)
public ResponseEntity getFoo(){
    // do something
} 
0
Chandan Kumar

Tôi đã tạo một cây cầu đơn giản trong miền của riêng mình để tìm nạp và hiển thị nội dung từ miền bên ngoài.

<?php
header("Content-Type: text/plain");
if (isset($_GET["cnic"]))
{
    $page = file_get_contents("https://external.domain.com/api/verify/" . $_GET["cnic"]);
    echo $page;
}
else
{
    echo "";
}

?>

Bây giờ, thay vì truy cập tên miền bên ngoài trong AJAX, tôi đã đặt URL của tệp cầu nối này.

Bạn nên điều chỉnh Content-Type theo nhu cầu của bạn. Nếu dữ liệu ở dạng JSON thì hãy sử dụng header("Content-Type: application/json");

0
Muhammad Saqib

Chỉ cần đề cập đến một cách khác để "bỏ qua" nó - proxy AJAX. Gửi yêu cầu đến máy chủ của bạn để lấy dữ liệu từ một Nguồn gốc khác và gửi lại yêu cầu cho bạn.

Tôi thích cách tiếp cận này hơn JSONP vì nó có một số vấn đề bảo mật tiềm ẩn.

0
carobnodrvo

Tôi đã giải quyết điều này bằng cách kích hoạt CORS cho URL khách truy cập API web và nó đã hoạt động thành công.

Ví dụ:

[EnableCors(origins: "http://clientaccessingapi.com", headers: "*", methods: "*")]
0
Rizwan ali