ข้อผิดพลาดในการควบคุมการเข้าถึงอนุญาตให้ส่ง jQuery Post ไปยัง Google API


143

ฉันอ่านข้อผิดพลาด 'Access-Control-Allow-Origin' มาก แต่ฉันไม่เข้าใจว่าต้องแก้ไขอะไร :(

ฉันกำลังเล่นกับ Google โมเดอเรเตอร์ API แต่เมื่อฉันพยายามเพิ่มเซเรียอาใหม่ฉันจะได้รับ:

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 ที่นี่ได้อย่างไรถ้าใช้เพราะฉันต้องเพิ่มหัวข้อการให้สิทธิ์และฉันไม่รู้วิธีใช้โดยไม่ใช้ beforeCall จาก $ .ajax: /

มีแสงสำหรับความมืดนี้หรือไม่?

นั่นคือรหัส:

<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

ฉันแก้ไขข้อผิดพลาดในการเข้าถึงการควบคุมการอนุญาตให้แก้ไขพารามิเตอร์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
Dave Baghdanov

5
@rubdottocom จะเกิดอะไรขึ้นถ้า url ส่งคืนการตอบกลับ xml แทนที่จะเป็น json ...
โต๊ะผู้พัฒนา

43

ฉันมีปัญหาเดียวกันและไม่ข้ามโดเมน แต่เป็นโดเมนเดียวกัน ฉันเพิ่งเพิ่มบรรทัดนี้ไปยังไฟล์ php ซึ่งจัดการคำขอ ajax

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

มันทำงานเหมือนจับใจ ขอบคุณโปสเตอร์


29
มันไม่ปลอดภัยมาก หากใครก็ตามสามารถฉีดจาวาสคริปต์ในหน้าของคุณพวกเขาสามารถ "โทรศัพท์บ้าน" ข้อมูลใด ๆ ที่ผู้ใช้อาจให้
dclowd9901

@ dclowd9901: "ไม่ปลอดภัย"เป็นญาติขึ้นอยู่กับวัตถุประสงค์ของการใช้งานและมาตรการการปฏิบัติสำหรับการตั้งค่าส่วนหัวของการเข้าถึงการควบคุมอนุญาตให้-แหล่งกำเนิดสินค้าที่จะไม่ระบุชื่อด้วยเหตุผลอื่น ๆ
nyedidikeke

6

หากคุณมีข้อผิดพลาดนี้พยายามที่จะใช้บริการที่คุณไม่สามารถเพิ่มส่วนหัวAccess-Control-Allow-Origin *ในแอปพลิเคชันนั้น แต่คุณสามารถใส่พร็อกซีย้อนกลับที่ด้านหน้าของเซิร์ฟเวอร์ข้อผิดพลาดสามารถหลีกเลี่ยงได้ด้วยการเขียนส่วนหัวใหม่

สมมติว่าแอปพลิเคชันทำงานบนพอร์ต 8080 (โดเมนสาธารณะที่www.mydomain.com ) และคุณใส่ reverse proxy ในโฮสต์เดียวกันที่พอร์ต 80 นี่คือการกำหนดค่าสำหรับNginx reverse proxy:

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
ดังที่กล่าวไว้ข้างต้นโดยใช้ '*' ไม่ปลอดภัยมาก
Adaddinsane

5
ใช่ แต่ขึ้นอยู่กับสิ่งที่คุณเปิดเผย หากคุณกำลังเผยแพร่ API สาธารณะโดยไม่ได้รับอนุญาตนั่นเป็นวิธี (กรณีของฉัน) ถ้าไม่ได้คุณ shoud ใช้ somethig Access-Control-Allow-Origin: http://example.comเช่นนี้
Mariano Ruiz

2
เมื่อฉันทดสอบ api ผ่านบุรุษไปรษณีย์และอาแจ็กซ์ แต่คำขอของบุรุษไปรษณีย์ก็ประสบความสำเร็จ แต่ในอาแจ็กซ์กลับเท็จ
Araf

@Araf บุรุษไปรษณีย์และแอปพลิเคชันอื่น ๆ ไม่เรียกใช้การป้องกัน CORS ที่สร้างขึ้นในเบราว์เซอร์
อาจารย์ SenseiHitokiri

6

ใช่ช่วงเวลาที่ jQuery เห็น URL เป็นของโดเมนอื่นถือว่าเป็นการโทรข้ามโดเมนดังนั้นจึงcrossdomain:trueไม่จำเป็นต้องใช้ที่นี่

นอกจากนี้สิ่งสำคัญที่ควรทราบคือคุณไม่สามารถโทรแบบซิงโครนัสได้$.ajaxหาก URL ของคุณเป็นของโดเมนอื่น (ข้ามโดเมน) หรือคุณกำลังใช้ JSONP อนุญาตให้เรียกใช้ async เท่านั้น

หมายเหตุ: คุณสามารถโทรหาบริการแบบซิงโครนัสได้หากคุณระบุ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 ของคุณ

และเราสามารถสร้างกิจกรรมบนคลิกวางกิจกรรมนี้บนปุ่มบางปุ่ม หวังว่านี่จะช่วยได้!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.