Помилка Access-Control-Allow-Origin при відправленні повідомлення про jQuery в API Google


143

Я багато читав за помилку "Access-Control-Allow-Origin", але не розумію, що мені потрібно виправити :(

Я граю з API Google Moderator, але коли я намагаюся додати нову серію, отримую:

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.

Я намагався з параметром зворотного виклику і без нього, я намагався додати до заголовка "Access-Control-Allow-Origin *". І я не знаю, як тут використовувати $ .getJSON, якщо це застосовується, тому що я повинен додати заголовок Авторизація, і я не знаю, як це зробити без callCall від $ .ajax: /

Будь-яке світло для цієї темряви uu?

Ось код:

<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
ви можете, будь ласка, поставити свій код трохи повніше? Я не міг запустити ваш код.
Хосейн Акаджані

Відповіді:


249

Я вирішив помилку Access-Control-Allow-Origin змінивши параметр dataType в dataType: 'jsonp' та додавши 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
Я не думаю, що crossDomain:trueце потрібно. Я розумію, що це потрібно лише в тому випадку, якщо ви робите запит на своєму власному домені, але хочете, щоб jQuery ставився до нього як до запиту між доменами.
Alex W

7
crossDomainне потрібен. це звичайний jsonpзапит, який призначений для міждоменного спілкування.
hitautodestruct

50
Я отримую таку ж помилку, але хочу опублікувати запит. jsonp не підтримує POST. Як я можу це вирішити?
iamjustcoder

7
Ви також змінили свій метод з POST на GET
Дейв Багданов

5
@rubdottocom що робити, якщо URL повертає відповідь xml замість json ...?
Desk Developer

43

У мене була точно та сама проблема, і це було не міждоменним, а тим самим доменом. Я щойно додав цей рядок до файлу php, який обробляв запит ajax.

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

Це спрацювало як шарм. Завдяки плакату


29
Це дуже небезпечно. Якщо комусь вдасться вставити javascript на вашу сторінку, він міг би легко "зателефонувати" будь-яку інформацію, яку може надати користувач.
dclowd9901

@ dclowd9901: "Небезпечно" відносно залежно від мети використання та заходів, що виконуються для встановлення заголовка Access-Control-Allow-Origin на анонімне серед інших причин.
nyedidikeke

6

Якщо у вас є помилка при спробі використання служби, яка не може додати заголовок Access-Control-Allow-Origin *у цій програмі, але ви можете поставити перед сервером зворотний проксі, помилку можна уникнути, якщо перезаписати заголовок.

Якщо припустити, що програма працює на порту 8080 (публічний домен на www.mydomain.com ), і ви помістите зворотний проксі-сервер у той самий хост на порту 80, це конфігурація для зворотного проксі-сервера 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
Як було сказано вище, використання "*" дуже небезпечно.
Ададдінсан

5
Так, але залежно від того, що ви викриваєте. Якщо ви публікуєте публічний API без дозволу, це спосіб (мій випадок). Якщо немає, вам слід бути використані somethig як це: Access-Control-Allow-Origin: http://example.com.
Маріано Руїз

2
коли я тестую api через листоношу та ajax. але прохання листоноші - успіх. але в Ajax повернення хибне.
Араф

@Araf листоноша та інші програми не спрацьовують захисту CORS, які вбудовані у браузери.
SenseiHitokiri

6

Так, момент, коли jQuery бачить URL належить до іншого домену, він передбачає, що виклик є перехресним викликом домену, тому crossdomain:trueтут не потрібно.

Також важливо зазначити, що ви не можете здійснювати синхронний дзвінок із $.ajax якщо ваша URL-адреса належить до іншого домену (крос-домену) або ви використовуєте JSONP. Дозволені лише дзвінки асинхронізації.

Примітка. Ви можете зателефонувати до служби синхронно, якщо вказати async:falseсвій запит.


0

У моєму випадку проблема доменного імені викликає проблему. Ось деталі

Я використав app_development.something.com, тут _піддомен підкреслення ( ) створює помилку CORS. Після зміни app_developmentна app-developmentнього працює чудово.


0

Є невеликий хак з php. І це працює не лише з Google, але і з будь-яким веб-сайтом, який ви не контролюєте, і не можете додати Access-Control-Allow-Origin *

Нам потрібно створити PHP-файл (наприклад, getContentFromUrl.php ) на нашому веб-сервері і зробити невелику хитрість.

PHP

<?php

$ext_url = $_POST['ext_url'];

echo file_get_contents($ext_url);

?>

JS

$.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');
    }
});

Як це працює:

  1. Ваш браузер за допомогою JS надішле запит на ваш сервер
  2. Ваш сервер надішле запит на будь-який інший сервер і отримає відповідь від іншого сервера (будь-якого веб-сайту)
  3. Ваш сервер надішле цю відповідь вашому JS

І ми можемо робити події onClick, покласти цю подію на якусь кнопку. Сподіваюся, це допоможе!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.