Origin ไม่ได้รับอนุญาตจาก Access-Control-Allow-Origin


337

ฉันกำลังAjax.requestเข้าสู่เซิร์ฟเวอร์ PHP ระยะไกลในแอปพลิเคชันSencha Touch 2 (รวมอยู่ในPhoneGap )

การตอบสนองจากเซิร์ฟเวอร์ต่อไปนี้:

XMLHttpRequest ไม่สามารถโหลดhttp://nqatalog.negroesquisso.pt/login.php Origin http://localhost:8888ไม่ได้รับอนุญาตจาก Access-Control-Allow-Origin

ฉันจะแก้ไขปัญหานี้ได้อย่างไร


19
ในขณะที่ใช้ jQuery การตั้งค่าdataType: 'jsonp',ก็ใช้กลอุบาย
amit

11
โดยวิธีการที่ไม่ตอบสนองจากเซิร์ฟเวอร์ เพื่อให้แม่นยำข้อผิดพลาดนั้นจะถูกออกในฝั่งไคลเอ็นต์
matteo

2
เคล็ดลับ jsonp อาจไม่ทำงานอีกต่อไป fyi: stackoverflow.com/questions/12216208/…
drewww

7
หมายเหตุเนื่องจากฉันเพิ่งเสียเวลาเพียงครึ่งวันในการติดตามข้อผิดพลาดนี้ - หากสคริปต์ฝั่งเซิร์ฟเวอร์ล้มเหลวด้วยข้อผิดพลาดภายในของเซิร์ฟเวอร์เบราว์เซอร์อาจตีความมันราวกับว่าคำขอไม่ได้รับอนุญาตเนื่องจากAccess-Control-Allow-Originและรายงานข้อผิดพลาดนี้
troelskn

1
@troelskn คุณเพียงช่วยชีวิตฉันไว้ ฉันกำลังค้นหาความผิดพลาดบางอย่างของ CORS ตั้งแต่ 3 วันและมันเป็นปัญหาการกำหนดค่าแบบสปริงเล็กน้อยที่ทำให้เกิด 500 ซึ่งฉันแก้ไขได้ภายใน 5 นาทีเมื่อฉันอ่านความคิดเห็นของคุณและฉันก็มองหามัน ขอบคุณ!
Alexis Dufrenoy

คำตอบ:


378

ผมเขียนบทความเกี่ยวกับเรื่องนี้กลับมาในขณะที่ครอส AJAX

วิธีที่ง่ายที่สุดในการจัดการสิ่งนี้หากคุณมีการควบคุมเซิร์ฟเวอร์ที่ตอบสนองคือการเพิ่มส่วนหัวการตอบกลับสำหรับ:

Access-Control-Allow-Origin: *

นี้จะช่วยให้ข้ามโดเมนอาแจ็กซ์ ใน PHP คุณจะต้องแก้ไขการตอบสนองดังนี้:

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

คุณสามารถHeader set Access-Control-Allow-Origin *ตั้งค่าไว้ในการกำหนดค่าApacheหรือไฟล์ htaccess

มันควรจะตั้งข้อสังเกตว่าเรื่องนี้ได้อย่างมีประสิทธิภาพจะปิดใช้งานการป้องกัน ธ ซึ่งน่าจะหมายความว่าผู้ใช้ของคุณที่จะถูกโจมตี หากคุณไม่ทราบว่าคุณต้องใช้ไวด์การ์ดโดยเฉพาะคุณไม่ควรใช้มันและคุณควรทำรายการโดเมนที่อนุญาตพิเศษ:

<?php header('Access-Control-Allow-Origin: http://example.com') ?>

4
ฉันจะติดต่อผู้ให้บริการเซิร์ฟเวอร์ของฉัน ขอบคุณ
Ricardo

8
มีข้อกังวลเรื่องความปลอดภัยหรือไม่? ตัวอย่างเช่นคำตอบนี้บอกว่า "JavaScript ถูก จำกัด โดย" นโยบายกำเนิดเดียวกัน "เพื่อเหตุผลด้านความปลอดภัยตัวอย่างเช่นสคริปต์ที่เป็นอันตรายไม่สามารถติดต่อเซิร์ฟเวอร์ระยะไกลและส่งข้อมูลที่ละเอียดอ่อนจากเว็บไซต์ของคุณ"
JohnK

4
ยอดเยี่ยมฉันเพิ่งใส่มันในไฟล์เซิร์ฟเวอร์ node.js ของฉัน: response.writeHead (200, {'Content-Type': contentType, 'Access-Control-Allow-Origin': '*'}); และมันก็ใช้งานได้ ขอบคุณ!
vbullinger

25
JohnK ใช่แล้ว wildcard จะอนุญาตให้โดเมนใด ๆ ส่งคำขอไปยังโฮสต์ของคุณ ฉันขอแนะนำให้แทนที่เครื่องหมายดอกจันด้วยโดเมนเฉพาะที่คุณจะใช้งานสคริปต์
นิค

7
เป็นเรื่องที่น่าสนใจที่คุณคิดว่าควรใช้สัญลักษณ์แทน @jfrej ทุกอย่างขึ้นอยู่กับเป้าหมายของคุณ ตัวอย่างเช่นเหตุผลที่เราใช้สัญลักษณ์แทน (และโพสต์คำตอบนี้) ก็เพราะเรากำลังสร้างวิดเจ็ตแบบฝังสำหรับเว็บไซต์ใด ๆ ที่จะใช้
Matt Mombrea

63

หากคุณไม่ได้มีการควบคุมของเซิร์ฟเวอร์คุณก็สามารถเพิ่มเรื่องนี้จะปล่อย Chrome --disable-web-securityของคุณ:

โปรดทราบว่าฉันจะไม่ใช้สิ่งนี้ในการ "ท่องเว็บ" ตามปกติ สำหรับการอ้างอิงดูโพสต์นี้: เดียวกันต้นทางนโยบายปิดการใช้งานใน Chrome

เมื่อคุณใช้ Phonegap เพื่อสร้างแอปพลิเคชั่นจริงและโหลดลงในอุปกรณ์นี่จะไม่มีปัญหา


ขอบคุณ แต่แอพของฉันทำงานบนอุปกรณ์มือถือฉันไม่สามารถส่งผ่านข้อโต้แย้งไปยัง wrapper เว็บวิวของฉันได้
Ricardo

คุณไม่ทดสอบแอปของคุณในเบราว์เซอร์ก่อนใช่หรือไม่ คุณจะแก้ปัญหาอย่างไร
Travis Webb

ใช่ฉันตรวจแก้จุดบกพร่องในเบราว์เซอร์ Chrome แต่แอปจะไม่ทำงานบน Chrome มันจะเป็นใน webgap แม่มดโทรศัพท์ webview ฉันไม่สามารถควบคุม
Ricardo

4
อ่านคำตอบ: คุณสามารถเพิ่มอาร์กิวเมนต์นี้ลงในตัวเรียกใช้งาน Chrome ของคุณได้ ไม่มีการตั้งค่าสำหรับสิ่งนี้ภายใน Chrome
Travis Webb

2
แน่นอนว่ามันไม่ปลอดภัย OP กำลังขอวิธีแก้ไขมาตรการรักษาความปลอดภัย
Travis Webb

42

หากคุณใช้ Apache เพียงเพิ่ม:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

ในการกำหนดค่าของคุณ นี่จะทำให้คำตอบทั้งหมดจากเว็บเซิร์ฟเวอร์ของคุณสามารถเข้าถึงได้จากเว็บไซต์อื่น ๆ บนอินเทอร์เน็ต หากคุณตั้งใจจะอนุญาตให้ใช้บริการบนโฮสต์ของคุณโดยเซิร์ฟเวอร์เฉพาะคุณสามารถแทนที่*ด้วย URL ของเซิร์ฟเวอร์ต้นทาง:

Header set Access-Control-Allow-Origin: http://my.origin.host

3
และอย่าลืมโหลดโมดูล: ส่วนหัว a2enmod
Walery Strauch

วิธีการโหลดโมดูล: a2enmod header?
Ayesha

18

หากคุณมีแอปพลิเคชันASP.NET / ASP.NET MVCคุณสามารถรวมส่วนหัวนี้ผ่านไฟล์ Web.config:

<system.webServer>
  ...

    <httpProtocol>
        <customHeaders>
            <!-- Enable Cross Domain AJAX calls -->
            <remove name="Access-Control-Allow-Origin" />
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

2
.NET MVC People ดูที่นี่! จริง ๆ แล้วฉันจะพิมพ์วิธีการแก้ปัญหาและชี้ไปที่คำตอบนี้ในบล็อกของฉันเพื่อให้ผู้คนสามารถค้นหาได้ง่ายขึ้น ไม่มีอะไรเลวร้ายยิ่งไปกว่าการพยายามผ่านอุปสรรค NET / MVC และค้นหาสิ่งใดนอกจาก PHP / jQuery ขอบคุณ @ Caio-Proiete
ottoflux

1
ทำไมสิ่งนี้ถึงไม่ได้ผลสำหรับฉัน ฉันใช้ Chrome และพยายามเข้าถึงหน้าการเงิน yahoo จาก localhost ของฉัน
นิวแมน

1
ขอบคุณมันใช้งานได้สำหรับฉัน ฉันได้เพิ่มเข้าไปในโปรเจคโค้ดฝั่งเซิร์ฟเวอร์ (web.config)
ethem

15

นี่เป็นคำถาม / คำตอบแรกที่โผล่ขึ้นมาสำหรับฉันเมื่อพยายามที่จะแก้ปัญหาเดียวกันโดยใช้ASP.NET MVCเป็นแหล่งข้อมูลของฉัน ฉันรู้ว่านี่ไม่ได้แก้คำถามPHPแต่มีความเกี่ยวข้องมากพอที่จะมีค่า

ฉันกำลังใช้ ASP.NET MVC บล็อกโพสต์จากเกร็กตัวผู้ทำงานให้ฉัน ในที่สุดคุณสร้างคุณลักษณะ[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]ที่คุณสามารถเพิ่มการกระทำของตัวควบคุม

ตัวอย่างเช่น:

public class HttpHeaderAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public HttpHeaderAttribute(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AppendHeader(Name, Value);
        base.OnResultExecuted(filterContext);
    }
}

จากนั้นใช้กับ:

[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
    return Json( "Some public result" );
}

1
WebApi 2 มีสิ่งนี้ในตัว asp.net/web-api/overview/security/…
Matt Frear

10

เนื่องจาก Matt Mombrea นั้นถูกต้องสำหรับฝั่งเซิร์ฟเวอร์คุณอาจพบปัญหาอื่นซึ่งเป็นการปฏิเสธรายการที่อนุญาตพิเศษ

คุณต้องกำหนดค่า phonegap.plist ของคุณ (ฉันใช้ phonegap รุ่นเก่า)

สำหรับ Cordova อาจมีการเปลี่ยนแปลงบางอย่างในการตั้งชื่อและไดเรกทอรี แต่ขั้นตอนส่วนใหญ่ควรเหมือนกัน

ก่อนอื่นให้เลือกไฟล์ที่รองรับ> PhoneGap.plist

ป้อนคำอธิบายรูปภาพที่นี่

จากนั้นภายใต้ "ExternalHosts"

เพิ่มรายการโดยอาจมีค่าเป็น " http://nqatalog.negroesquisso.pt " ฉันใช้ * เพื่อการดีบักเท่านั้น

ป้อนคำอธิบายรูปภาพที่นี่


8

สิ่งนี้อาจมีประโยชน์สำหรับทุกคนที่ต้องการยกเว้นผู้อ้างอิงทั้งรุ่น 'www' และ 'ไม่ใช่ www':

 $referrer = $_SERVER['HTTP_REFERER'];
 $parts = parse_url($referrer);
 $domain = $parts['host'];

 if($domain == 'google.com')
 {
         header('Access-Control-Allow-Origin: http://google.com');
 }
 else if($domain == 'www.google.com')
 {
         header('Access-Control-Allow-Origin: http://www.google.com');
 }

ชี้ให้ฉันเห็นทิศทางที่ถูกต้องในการแก้ไขข้อผิดพลาด ACAO ด้วยสีฟ้า ขณะที่ฉันเพิ่มชื่อโฮสต์ของ googledrive ที่ได้รับอนุญาต URL ที่ใช้จะต้องเป็นgoogledriveไม่ใช่googledrive
Kildareflare

7

ฉันจะให้คำตอบง่ายๆสำหรับคุณ ในกรณีของฉันฉันไม่สามารถเข้าถึงเซิร์ฟเวอร์ ในกรณีนี้คุณสามารถเปลี่ยนนโยบายความปลอดภัยในเบราว์เซอร์Google Chromeของคุณเพื่ออนุญาตการเข้าถึง - การควบคุม - อนุญาต - กำเนิด ง่ายมาก:

  1. สร้างทางลัดเบราว์เซอร์ Chrome
  2. คลิกขวาที่ไอคอนทางลัด -> คุณสมบัติ -> ทางลัด -> เป้าหมาย

"C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-securityวางที่เรียบง่ายใน

สถานที่อาจแตกต่างกัน ตอนนี้เปิด Chrome โดยคลิกที่ทางลัดนั้น


7

ฉันพบปัญหานี้สองสามครั้งเมื่อทำงานกับ API ที่หลากหลาย บ่อยครั้งที่การแก้ไขด่วนคือการเพิ่ม "& callback =?" ไปยังจุดสิ้นสุดของสตริง บางครั้งเครื่องหมายแอมเปอร์แซนด์ต้องเป็นรหัสตัวอักษรและบางครั้งจะเป็น "?": "? callback =?" (ดูการใช้งาน Forecast.io API กับ jQuery )


6

หากคุณกำลังเขียนขยาย Chrome และได้รับข้อผิดพลาดนี้แล้วให้แน่ใจว่าคุณได้เพิ่ม URL ฐาน API เพื่อคุณmanifest.json's สิทธิ์บล็อก , ตัวอย่างเช่น:

"permissions": [
    "https://itunes.apple.com/"
]

6

นี่เป็นเพราะนโยบายที่มาเดียวกัน ดูเพิ่มเติมได้ที่Mozilla พัฒนาเครือข่ายหรือวิกิพีเดีย

โดยทั่วไปในตัวอย่างของคุณคุณจะต้องโหลดhttp://nqatalog.negroesquisso.pt/login.phpหน้าเพียงไม่nqatalog.negroesquisso.ptlocalhost


1
แต่ฉันต้องโหลดเว็บเซอร์จากอุปกรณ์มือถือฉันจะข้ามมันได้หรือไม่
Ricardo

คุณต้องทำการเปลี่ยนแปลงด้านเซิร์ฟเวอร์หรือใช้ JSONP en.wikipedia.org/wiki/JSONP
antyrat

6

หากคุณอยู่ภายใต้ apache เพียงเพิ่มไฟล์. htaccess ในไดเรกทอรีของคุณด้วยเนื้อหานี้:

Header set Access-Control-Allow-Origin: *

Header set Access-Control-Allow-Headers: content-type

Header set Access-Control-Allow-Methods: *

5

ในRuby on Railsคุณสามารถทำได้ในคอนโทรลเลอร์:

headers['Access-Control-Allow-Origin'] = '*'

คุณใช้คอนโทรลเลอร์ตัวใดในการเรียก ajax? ฉันสามารถดูบริบทรหัสเพิ่มเติมได้หรือไม่
rigdonmr

5

คุณสามารถทำให้มันทำงานได้โดยไม่ต้องดัดแปลงเซิร์ฟเวอร์ด้วยการทำ broswer รวมถึงส่วนหัวAccess-Control-Allow-Origin: *ในการตอบสนองของ HTTP OPTIONS

ใน Chrome ใช้ส่วนขยายนี้ หากคุณใช้ Mozilla โปรดตรวจสอบคำตอบนี้


5

หากคุณได้รับสิ่งนี้ใน Angular.js ให้แน่ใจว่าคุณหลีกเลี่ยงหมายเลขพอร์ตของคุณเช่นนี้

var Project = $resource(
    'http://localhost\\:5648/api/...', {'a':'b'}, {
        update: { method: 'PUT' }
    }
);

ดูที่นี่สำหรับข้อมูลเพิ่มเติมเกี่ยวกับมัน


4

เรามีปัญหาเดียวกันกับแอปพลิเคชั่น phonegap ที่ทดสอบด้วยโครเมี่ยม เครื่อง windows หนึ่งเครื่องที่เราใช้ไฟล์ชุดด้านล่างทุกวันก่อนเปิด Chrome จำไว้ว่าก่อนใช้งานสิ่งนี้คุณต้องทำความสะอาดโครเมี่ยมทั้งหมดจากตัวจัดการงานหรือคุณสามารถเลือก chrome เพื่อไม่ให้ทำงานในพื้นหลัง

ชุด: (ใช้ cmd)

cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security


0

เมื่อคุณได้รับคำขอคุณสามารถ

var origin = (req.headers.origin || "*");

กว่าเมื่อคุณต้องตอบกลับด้วยสิ่งที่ต้องการ:

res.writeHead(
    206,
    {
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Origin': origin,
    }
);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.