ค้นหาเว็บไซต์

javascript - ฟิลด์หัวข้อคำขอ Access-Control-Allow-Headers ไม่ได้รับอนุญาตโดย Access-Control-Allow-Headers


ฉันกำลังพยายามส่งไฟล์ไปยังเซิร์ฟเวอร์ของฉันด้วยคำขอแบบโพสต์ แต่เมื่อส่งแล้วจะทำให้เกิดข้อผิดพลาด:

ฟิลด์เฮดเดอร์ของคำร้อง Content-Type ไม่ได้รับอนุญาตโดย Access-Control-Allow-Headers

ดังนั้นฉันจึงค้นหาข้อผิดพลาดในกูเกิลและเพิ่มหัวเรื่อง:

$http.post($rootScope.URL, {params: arguments}, {headers: {
    "Access-Control-Allow-Origin" : "*",
    "Access-Control-Allow-Methods" : "GET,POST,PUT,DELETE,OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
}

แล้วฉันก็ได้รับข้อผิดพลาด:

ฟิลด์เฮดเดอร์คำร้องขอ Access-Control-Allow-Origin ไม่ได้รับอนุญาตโดย Access-Control-Allow-Headers

ดังนั้นฉันจึงค้นหาจากกูเกิลและคำถามที่คล้ายที่สุดที่ฉันหาพบได้รับคำตอบครึ่งหนึ่งแล้วถูกปิดเพราะนอกหัวข้อ ฉันควรเพิ่ม/ลบหัวข้ออะไรบ้าง?

คำตอบ #1

ฉันก็มีปัญหาแบบเดียวกัน ในเอกสารของ jQuery ฉันพบว่า:

สำหรับคำขอข้ามโดเมน การตั้งค่าประเภทเนื้อหาเป็นสิ่งอื่นใดนอกจาก application/x-www-form-urlencoded, multipart/form-data หรือ text/plain จะทำให้เบราว์เซอร์ส่งคำขอ OPTIONS แบบ preflight ไปยังเซิร์ฟเวอร์

ดังนั้นแม้ว่าเซิร์ฟเวอร์จะอนุญาตคำขอข้ามต้นทาง แต่ถ้าไม่อนุญาต Access-Control-Allow-Headers ก็จะเกิดข้อผิดพลาด โดยค่าเริ่มต้นชนิดเนื้อหาของ Angular คือ application/json ซึ่งพยายามส่งคำขอแบบ OPTION ลองเขียนทับเฮดเดอร์เริ่มต้นของ Angular หรืออนุญาต Access-Control-Allow-Headers ที่ฝั่งเซิร์ฟเวอร์ นี่คือตัวอย่าง Angular:

$http.post(url, data, {
    headers : {
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
    }
});

คำตอบ #2

เซิร์ฟเวอร์ (server) (ที่ส่งคำขอ POST ไป) จำเป็นต้องรวมส่วนหัว Access-Control-Allow-Headers (และอื่น ๆ) ในคำตอบของมัน การใส่สิ่งเหล่านี้ในคำขอจากฝั่งลูกค้าไม่มีผลใด ๆ คุณควรลบส่วนหัว 'Access-Control-Allow-...' ออกจากคำขอ POST ของคุณ

นี่เป็นเพราะขึ้นอยู่กับเซิร์ฟเวอร์ที่จะระบุว่ามันยอมรับคำขอข้ามแหล่งที่มา (และว่ามันอนุญาตให้ใช้หัวข้อคำขอ Content-Type และอื่น ๆ) - ฝั่งไคลเอนต์ไม่สามารถตัดสินใจด้วยตัวเองได้ว่าเซิร์ฟเวอร์ใดควรอนุญาต CORS.

ผู้ร้องขอ (เว็บเบราว์เซอร์) อาจทำการทดสอบ 'preflight' ว่านโยบาย Same Origin ของเซิร์ฟเวอร์เป็นอย่างไรโดยการส่งคำขอ 'OPTIONS' (เช่น ไม่ใช่คำขอ 'POST' หรือ 'GET' ที่คุณตั้งใจจะส่ง) หากการตอบสนองต่อคำขอ 'OPTIONS' มีส่วนหัว 'Access-Control-Allow-...' ที่อนุญาตให้ใช้ส่วนหัว ต้นกำเนิด หรือวิธีการที่คำขอของคุณใช้ เบราว์เซอร์/ผู้ร้องขอจะส่งคำขอ 'POST' หรือ 'GET' ของคุณ

(หมายเหตุที่ไม่ชัดเจน:) ค่า Access-Control-Allow-... คือ '<em></em>' แทนที่จะระบุต้นกำเนิด, เฮดเดอร์, หรือวิธีที่อนุญาตอย่างเฉพาะเจาะจง อย่างไรก็ตาม ลูกค้า Android WebView รุ่นเก่าที่ฉันใช้อยู่ไม่ได้ยอมรับ '</em>' wildcard และต้องระบุเฮดเดอร์เฉพาะใน Access-Control-Allow-Headers header ในการตอบกลับคำขอ OPTIONS

คำตอบ #3

ถ้านั่นช่วยใครได้บ้าง (แม้ว่าสิ่งนี้อาจจะไม่ดีนักเนื่องจากเราต้องอนุญาตสิ่งนี้เฉพาะเพื่อวัตถุประสงค์ในการพัฒนา) นี่คือวิธีแก้ปัญหาใน Java เนื่องจากฉันเจอปัญหาเดียวกัน [แก้ไข] อย่าใช้สัญลักษณ์ตัวแทน * เนื่องจากเป็นวิธีแก้ปัญหาที่ไม่ดี ใช้ localhost หากคุณต้องการให้บางอย่างทำงานในเครื่องได้จริง ๆ

public class SimpleCORSFilter implements Filter {

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "my-authorized-proxy-or-domain");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    chain.doFilter(req, res);
}

public void init(FilterConfig filterConfig) {}

public void destroy() {}

}

คำตอบ #4

คุณสามารถเปิดใช้งานเฮดเดอร์ที่เหมาะสมใน PHP ได้ด้วยสิ่งนี้:

header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, X-Requested-With");

คำตอบ #5

เซิร์ฟเวอร์ (ที่ส่งคำร้อง POST ไป) ต้องรวมส่วนหัว Content-Type ในการตอบกลับของมัน

นี่คือลิสต์ของหัวข้อมาตรฐานที่ควรรวมไว้ รวมถึงหัวข้อกำหนดเองหนึ่งรายการ "X_ACCESS_TOKEN":

"X-ACCESS_TOKEN", "Access-Control-Allow-Origin", "Authorization", "Origin", "x-requested-with", "Content-Type", "Content-Range", "Content-Disposition", "Content-Description"

นั่นคือสิ่งที่คนดูแลเซิร์ฟเวอร์ HTTP ของคุณต้องตั้งค่าสำหรับเว็บเซิร์ฟเวอร์ที่คุณส่งคำขอไป

คุณอาจต้องการขอให้ฝ่ายเซิร์ฟเวอร์ของคุณเปิดเผยหัวข้อ "Content-Length"

เขาจะรับรู้ว่านี่คือคำร้องขอการแชร์ทรัพยากรข้ามต้นทาง (CORS) และควรเข้าใจผลกระทบของการทำการกำหนดค่าของเซิร์ฟเวอร์เหล่านั้น

ดูรายละเอียดได้ที่:

  • http://www.w3.org/TR/cors/
  • http://enable-cors.org/

บทความที่เกี่ยวข้อง