Lỗi Kiểm soát truy cập-Cho phép-Xuất xứ gửi Bài đăng jQuery đến Google API


143

Tôi đã đọc rất nhiều về lỗi 'Kiểm soát truy cập-Cho phép-Xuất xứ', nhưng tôi không hiểu những gì tôi phải sửa :(

Tôi đang chơi với Google Moderator API, nhưng khi tôi thử thêm serie mới, tôi nhận được:

XMLHttpRequest cannot load 
https://www.googleapis.com/moderator/v1/series?key=[key]
&data%5Bdescription%5D=Share+and+rank+tips+for+eating+healthily+on+the+cheaps!
&data%5Bname%5D=Eating+Healthy+%26+Cheap
&data%5BvideoSubmissionAllowed%5D=false. 
Origin [my_domain] is not allowed by Access-Control-Allow-Origin.

Tôi đã thử với và không có tham số gọi lại, tôi đã thử thêm 'Access-Control-Allow-Origin *' vào tiêu đề. Và tôi không biết cách sử dụng $ .getJSON ở đây, nếu áp dụng, vì tôi phải thêm tiêu đề Ủy quyền và tôi không biết cách thực hiện mà không có trướcCall từ $ .ajax: /

Bất kỳ ánh sáng cho bóng tối này uu?

Đó là mã:

<script src="http://www.google.com/jsapi"></script>

<script type="text/javascript">

var scope = "https://www.googleapis.com/auth/moderator";
var token = '';

function create(){
     if (token == '')
      token = doCheck();

     var myData = {
      "data": {
        "description": "Share and rank tips for eating healthily on the cheaps!", 
        "name": "Eating Healthy & Cheap", 
        "videoSubmissionAllowed": false
      }
    };

    $.ajax({

        url: 'https://www.googleapis.com/moderator/v1/series?key='+key,
        type: 'POST',
        callback: '?',
        data: myData,
        datatype: 'application/json',
        success: function() { alert("Success"); },
        error: function() { alert('Failed!'); },
        beforeSend: setHeader

    });
}

function setHeader(xhr) {

  xhr.setRequestHeader('Authorization', token);
}

function doLogin(){ 
    if (token == ''){
       token = google.accounts.user.login(scope);
    }else{
       alert('already logged');
    }
}


function doCheck(){             
    token = google.accounts.user.checkLogin(scope);
    return token;
}
</script>
...
...
<div data-role="content">
    <input type="button" value="Login" onclick="doLogin();">
    <input type="button" value="Get data" onclick="getModerator();">
    <input type="button" value="Create" onclick="create();">
</div><!-- /content -->

1
bạn có thể vui lòng đặt mã của bạn một chút hoàn toàn? Tôi không thể chạy mã của bạn.
Hosein Aqajani

Câu trả lời:


249

Tôi đã giải quyết lỗi Access-Control-Allow-Origin sửa đổi tham số dataType thành dataType: 'jsonp' và thêm crossDomain: true

$.ajax({

    url: 'https://www.googleapis.com/moderator/v1/series?key='+key,
    data: myData,
    type: 'GET',
    crossDomain: true,
    dataType: 'jsonp',
    success: function() { alert("Success"); },
    error: function() { alert('Failed!'); },
    beforeSend: setHeader
});

20
Tôi không nghĩ crossDomain:truelà bắt buộc. Tôi hiểu rằng nó chỉ cần thiết nếu bạn đang thực hiện một yêu cầu trên tên miền của riêng bạn nhưng muốn jQuery coi nó như một yêu cầu tên miền chéo.
Alex W

7
crossDomainkhông cần thiết đây là một jsonpyêu cầu thường xuyên có nghĩa là để liên lạc giữa các miền.
hitautodesturation

50
Tôi nhận được lỗi tương tự, nhưng tôi muốn gửi yêu cầu. jsonp sẽ không hỗ trợ POST. Làm thế nào tôi có thể giải quyết điều này?
iamjustcoder

7
Bạn cũng đã thay đổi phương thức của mình từ POST thành GET
Dave Baghdanov

5
@rubdottocom nếu url trả về phản hồi xml thay vì json ...?
Bàn phát triển

43

Tôi đã có chính xác cùng một vấn đề và đó không phải là tên miền chéo mà là cùng một tên miền. Tôi vừa thêm dòng này vào tệp php đang xử lý yêu cầu ajax.

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

Nó làm việc như một say mê. Cảm ơn người đăng


29
Điều này rất không an toàn. Nếu bất cứ ai quản lý để đưa javascript vào trang của bạn, họ có thể dễ dàng "gọi điện về nhà" bất kỳ thông tin nào mà người dùng có thể cung cấp.
dclowd9901

@ dclowd9901: "Không an toàn" là tương đối tùy thuộc vào mục đích sử dụng và các biện pháp được quan sát để đặt tiêu đề Access-Control-Allow-Origin thành ẩn danh trong số các lý do khác.
nyedidikeke

6

Nếu bạn gặp lỗi này khi cố gắng sử dụng một dịch vụ mà bạn không thể thêm tiêu đề Access-Control-Allow-Origin *trong ứng dụng đó, nhưng bạn có thể đặt trước máy chủ một proxy ngược, lỗi có thể tránh được khi viết lại tiêu đề.

Giả sử ứng dụng đang chạy trên cổng 8080 (miền công cộng tại www.mydomain.com ) và bạn đặt proxy ngược trong cùng một máy chủ tại cổng 80, đây là cấu hình cho proxy ngược Nginx :

server {
    listen      80;
    server_name www.mydomain.com;
    access_log  /var/log/nginx/www.mydomain.com.access.log;
    error_log   /var/log/nginx/www.mydomain.com.error.log;

    location / {
        proxy_pass   http://127.0.0.1:8080;
        add_header   Access-Control-Allow-Origin *;
    }   
}

2
Như đã đề cập ở trên, sử dụng '*' là rất không an toàn.
Adaddinsane

5
Có, nhưng tùy thuộc vào những gì bạn đang phơi bày. Nếu bạn đang xuất bản API công khai mà không được phép, đó là cách (trường hợp của tôi). Nếu không, bạn nên sử dụng đôi khi như thế này : Access-Control-Allow-Origin: http://example.com.
Mariano Ruiz

2
khi tôi kiểm tra một api thông qua postman và ajax. nhưng yêu cầu người đưa thư là thành công. nhưng trong ajax trả về false.
Araf

@Araf postman và các ứng dụng khác không kích hoạt bảo vệ CORS được tích hợp trong trình duyệt.
SenseiHitokiri

6

Đúng, thời điểm jQuery thấy URL thuộc về một tên miền khác, nó giả định rằng cuộc gọi đó là một cuộc gọi tên miền chéo, do đó crossdomain:truekhông bắt buộc ở đây.

Ngoài ra, điều quan trọng cần lưu ý là bạn không thể thực hiện cuộc gọi đồng bộ $.ajaxnếu URL của bạn thuộc về một tên miền khác (tên miền chéo) hoặc bạn đang sử dụng JSONP. Chỉ cho phép các cuộc gọi async.

Lưu ý: bạn có thể gọi dịch vụ một cách đồng bộ nếu bạn chỉ định async:falsevới yêu cầu của mình.


0

Trong trường hợp của tôi, tên miền phụ gây ra vấn đề. Dưới đây là chi tiết

Tôi đã sử dụng app_development.something.com, ở đây _tên miền phụ gạch dưới ( ) đang tạo ra lỗi CORS. Sau khi thay đổi app_developmentđể app-developmentnó hoạt động tốt.


0

Có một chút hack với php. Và nó hoạt động không chỉ với Google, mà với bất kỳ trang web nào bạn không kiểm soát và không thể thêm Kiểm soát truy cập-Cho phép-Xuất xứ *

Chúng ta cần tạo tệp PHP (ví dụ: getContentFromUrl.php ) trên máy chủ web của mình và thực hiện một mẹo nhỏ.

PHP

<?php

$ext_url = $_POST['ext_url'];

echo file_get_contents($ext_url);

?>

Mã não

$.ajax({
    method: 'POST',
    url: 'getContentFromUrl.php', // link to your PHP file
    data: {
        // url where our server will send request which can't be done by AJAX
        'ext_url': '/programming/6114436/access-control-allow-origin-error-sending-a-jquery-post-to-google-apis'
    },
    success: function(data) {
        // we can find any data on external url, cause we've got all page
        var $h1 = $(data).find('h1').html();

        $('h1').val($h1);
    },
    error:function() {
        console.log('Error');
    }
});

Làm thế nào nó hoạt động:

  1. Trình duyệt của bạn với sự trợ giúp của JS sẽ gửi yêu cầu đến máy chủ của bạn
  2. Máy chủ của bạn sẽ gửi yêu cầu đến bất kỳ máy chủ nào khác và nhận phản hồi từ máy chủ khác (bất kỳ trang web nào)
  3. Máy chủ của bạn sẽ gửi trả lời này đến JS của bạn

Và chúng ta có thể tạo sự kiện trên Click, đặt sự kiện này vào một số nút. Hy vọng điều này sẽ giúp!

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.