Ký tự đại diện CORS Access-Control-Allow-Headers bị bỏ qua?


118

Tôi gặp sự cố khi yêu cầu CORS miền chéo hoạt động bình thường khi sử dụng Chrome.

Yêu cầu Tiêu đề:

Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4

Tiêu đề phản hồi:

Access-Control-Allow-Headers:*
Access-Control-Allow-Origin:*
Allow:GET, POST, OPTIONS
Content-Length:0
Date:Tue, 30 Oct 2012 20:04:28 GMT
Server:BaseHTTP/0.3 Python/2.7.3

Lỗi:

XMLHttpRequest cannot load domain. Request header field Content-Type is not allowed by Access-Control-Allow-Headers.

Và mã python phục vụ yêu cầu tùy chọn là:

self.send_response(200)
self.send_header('Allow', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Headers', '*')
self.send_header('Content-Length', '0')
self.end_headers()

Có vẻ như Access-Control-Allow-Originký tự đại diện đang bị bỏ qua?

Câu trả lời:


185

Hỗ trợ cho các ký tự đại diện trong Access-Control-Allow-Headerstiêu đề chỉ được thêm vào mức sống vào tháng 5 năm 2016, vì vậy nó có thể không được tất cả các trình duyệt hỗ trợ. Trên trình duyệt chưa triển khai điều này, nó phải là một trình duyệt trùng khớp chính xác: https://www.w3.org/TR/2014/REC-cors-20140116/#access-control-allow-headers-response-header

Nếu bạn mong đợi một số lượng lớn tiêu đề, bạn có thể đọc giá trị của Access-Control-Request-Headerstiêu đề và lặp lại giá trị đó trong Access-Control-Allow-Headerstiêu đề.


55
resp.setHeader ("Access-Control-Allow-Headers", req.getHeader ("Access-Control-Request-Headers")); // cho phép bất kỳ tiêu đề nào
Sam Barnum

3
Trên ruby, "if request.headers ['Access-Control-Request-Headers'] thì headers ['Access-Control-Allow-Headers'] = request.headers ['Access-Control-Request-Headers'] end" trông ok cho tôi.
Tsuneo Yoshioka

1
@monsur: câu trả lời này chỉ ra rằng ký tự đại diện hiện được phép, ít nhất là trên lý thuyết, vì vậy tôi đã cập nhật câu trả lời của bạn để phản ánh điều này. Nếu bạn không thích phong cách của tôi, hãy thoải mái chỉnh sửa theo sở thích của bạn.
MvG

2
Một lời cảnh báo, bạn có thể gặp rắc rối khi dựa vào việc chuyển lại giá trị Access-Control-Request-Headers nếu bạn cũng cho phép trình duyệt lưu vào bộ nhớ cache phản hồi preflight (với Access-Control-Max-Age). Bạn không biết rằng yêu cầu đầu tiên liệt kê tất cả các tiêu đề của các yêu cầu liên tiếp.
Simon Ejsing

2
@monokrome sẽ thật tuyệt nếu bạn có thể cho chúng tôi biết đây sẽ là mối lo ngại về bảo mật trong sản xuất như thế nào ..
khávoid

52

Các tiêu đề CORS đó không hỗ trợ *dưới dạng giá trị, cách duy nhất là thay thế *bằng:

Accept, Accept-CH, Accept-Charset, Accept-Datetime, Accept-Encoding, Accept-Ext, Accept-Features, Accept-Language, Accept-Params, Accept-Ranges, Access-Control-Allow-Credentials, Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Expose-Headers, Access-Control-Max-Age, Access-Control-Request-Headers, Access-Control-Request-Method, Age, Allow, Alternates, Authentication-Info, Authorization, C-Ext, C-Man, C-Opt, C-PEP, C-PEP-Info, CONNECT, Cache-Control, Compliance, Connection, Content-Base, Content-Disposition, Content-Encoding, Content-ID, Content-Language, Content-Length, Content-Location, Content-MD5, Content-Range, Content-Script-Type, Content-Security-Policy, Content-Style-Type, Content-Transfer-Encoding, Content-Type, Content-Version, Cookie, Cost, DAV, DELETE, DNT, DPR, Date, Default-Style, Delta-Base, Depth, Derived-From, Destination, Differential-ID, Digest, ETag, Expect, Expires, Ext, From, GET, GetProfile, HEAD, HTTP-date, Host, IM, If, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Keep-Alive, Label, Last-Event-ID, Last-Modified, Link, Location, Lock-Token, MIME-Version, Man, Max-Forwards, Media-Range, Message-ID, Meter, Negotiate, Non-Compliance, OPTION, OPTIONS, OWS, Opt, Optional, Ordering-Type, Origin, Overwrite, P3P, PEP, PICS-Label, POST, PUT, Pep-Info, Permanent, Position, Pragma, ProfileObject, Protocol, Protocol-Query, Protocol-Request, Proxy-Authenticate, Proxy-Authentication-Info, Proxy-Authorization, Proxy-Features, Proxy-Instruction, Public, RWS, Range, Referer, Refresh, Resolution-Hint, Resolver-Location, Retry-After, Safe, Sec-Websocket-Extensions, Sec-Websocket-Key, Sec-Websocket-Origin, Sec-Websocket-Protocol, Sec-Websocket-Version, Security-Scheme, Server, Set-Cookie, Set-Cookie2, SetProfile, SoapAction, Status, Status-URI, Strict-Transport-Security, SubOK, Subst, Surrogate-Capability, Surrogate-Control, TCN, TE, TRACE, Timeout, Title, Trailer, Transfer-Encoding, UA-Color, UA-Media, UA-Pixels, UA-Resolution, UA-Windowpixels, URI, Upgrade, User-Agent, Variant-Vary, Vary, Version, Via, Viewport-Width, WWW-Authenticate, Want-Digest, Warning, Width, X-Content-Duration, X-Content-Security-Policy, X-Content-Type-Options, X-CustomHeader, X-DNSPrefetch-Control, X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto, X-Frame-Options, X-Modified, X-OTHER, X-PING, X-PINGOTHER, X-Powered-By, X-Requested-With


.htaccess Ví dụ (Bao gồm CORS):

<IfModule mod_headers.c>
  Header unset Connection
  Header unset Time-Zone
  Header unset Keep-Alive
  Header unset Access-Control-Allow-Origin
  Header unset Access-Control-Allow-Headers
  Header unset Access-Control-Expose-Headers
  Header unset Access-Control-Allow-Methods
  Header unset Access-Control-Allow-Credentials

  Header set   Connection                         keep-alive
  Header set   Time-Zone                          "Asia/Jerusalem"
  Header set   Keep-Alive                         timeout=100,max=500
  Header set   Access-Control-Allow-Origin        "*"
  Header set   Access-Control-Allow-Headers       "Accept, Accept-CH, Accept-Charset, Accept-Datetime, Accept-Encoding, Accept-Ext, Accept-Features, Accept-Language, Accept-Params, Accept-Ranges, Access-Control-Allow-Credentials, Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Expose-Headers, Access-Control-Max-Age, Access-Control-Request-Headers, Access-Control-Request-Method, Age, Allow, Alternates, Authentication-Info, Authorization, C-Ext, C-Man, C-Opt, C-PEP, C-PEP-Info, CONNECT, Cache-Control, Compliance, Connection, Content-Base, Content-Disposition, Content-Encoding, Content-ID, Content-Language, Content-Length, Content-Location, Content-MD5, Content-Range, Content-Script-Type, Content-Security-Policy, Content-Style-Type, Content-Transfer-Encoding, Content-Type, Content-Version, Cookie, Cost, DAV, DELETE, DNT, DPR, Date, Default-Style, Delta-Base, Depth, Derived-From, Destination, Differential-ID, Digest, ETag, Expect, Expires, Ext, From, GET, GetProfile, HEAD, HTTP-date, Host, IM, If, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Keep-Alive, Label, Last-Event-ID, Last-Modified, Link, Location, Lock-Token, MIME-Version, Man, Max-Forwards, Media-Range, Message-ID, Meter, Negotiate, Non-Compliance, OPTION, OPTIONS, OWS, Opt, Optional, Ordering-Type, Origin, Overwrite, P3P, PEP, PICS-Label, POST, PUT, Pep-Info, Permanent, Position, Pragma, ProfileObject, Protocol, Protocol-Query, Protocol-Request, Proxy-Authenticate, Proxy-Authentication-Info, Proxy-Authorization, Proxy-Features, Proxy-Instruction, Public, RWS, Range, Referer, Refresh, Resolution-Hint, Resolver-Location, Retry-After, Safe, Sec-Websocket-Extensions, Sec-Websocket-Key, Sec-Websocket-Origin, Sec-Websocket-Protocol, Sec-Websocket-Version, Security-Scheme, Server, Set-Cookie, Set-Cookie2, SetProfile, SoapAction, Status, Status-URI, Strict-Transport-Security, SubOK, Subst, Surrogate-Capability, Surrogate-Control, TCN, TE, TRACE, Timeout, Title, Trailer, Transfer-Encoding, UA-Color, UA-Media, UA-Pixels, UA-Resolution, UA-Windowpixels, URI, Upgrade, User-Agent, Variant-Vary, Vary, Version, Via, Viewport-Width, WWW-Authenticate, Want-Digest, Warning, Width, X-Content-Duration, X-Content-Security-Policy, X-Content-Type-Options, X-CustomHeader, X-DNSPrefetch-Control, X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto, X-Frame-Options, X-Modified, X-OTHER, X-PING, X-PINGOTHER, X-Powered-By, X-Requested-With"
  Header set   Access-Control-Expose-Headers      "Accept, Accept-CH, Accept-Charset, Accept-Datetime, Accept-Encoding, Accept-Ext, Accept-Features, Accept-Language, Accept-Params, Accept-Ranges, Access-Control-Allow-Credentials, Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Expose-Headers, Access-Control-Max-Age, Access-Control-Request-Headers, Access-Control-Request-Method, Age, Allow, Alternates, Authentication-Info, Authorization, C-Ext, C-Man, C-Opt, C-PEP, C-PEP-Info, CONNECT, Cache-Control, Compliance, Connection, Content-Base, Content-Disposition, Content-Encoding, Content-ID, Content-Language, Content-Length, Content-Location, Content-MD5, Content-Range, Content-Script-Type, Content-Security-Policy, Content-Style-Type, Content-Transfer-Encoding, Content-Type, Content-Version, Cookie, Cost, DAV, DELETE, DNT, DPR, Date, Default-Style, Delta-Base, Depth, Derived-From, Destination, Differential-ID, Digest, ETag, Expect, Expires, Ext, From, GET, GetProfile, HEAD, HTTP-date, Host, IM, If, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Keep-Alive, Label, Last-Event-ID, Last-Modified, Link, Location, Lock-Token, MIME-Version, Man, Max-Forwards, Media-Range, Message-ID, Meter, Negotiate, Non-Compliance, OPTION, OPTIONS, OWS, Opt, Optional, Ordering-Type, Origin, Overwrite, P3P, PEP, PICS-Label, POST, PUT, Pep-Info, Permanent, Position, Pragma, ProfileObject, Protocol, Protocol-Query, Protocol-Request, Proxy-Authenticate, Proxy-Authentication-Info, Proxy-Authorization, Proxy-Features, Proxy-Instruction, Public, RWS, Range, Referer, Refresh, Resolution-Hint, Resolver-Location, Retry-After, Safe, Sec-Websocket-Extensions, Sec-Websocket-Key, Sec-Websocket-Origin, Sec-Websocket-Protocol, Sec-Websocket-Version, Security-Scheme, Server, Set-Cookie, Set-Cookie2, SetProfile, SoapAction, Status, Status-URI, Strict-Transport-Security, SubOK, Subst, Surrogate-Capability, Surrogate-Control, TCN, TE, TRACE, Timeout, Title, Trailer, Transfer-Encoding, UA-Color, UA-Media, UA-Pixels, UA-Resolution, UA-Windowpixels, URI, Upgrade, User-Agent, Variant-Vary, Vary, Version, Via, Viewport-Width, WWW-Authenticate, Want-Digest, Warning, Width, X-Content-Duration, X-Content-Security-Policy, X-Content-Type-Options, X-CustomHeader, X-DNSPrefetch-Control, X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto, X-Frame-Options, X-Modified, X-OTHER, X-PING, X-PINGOTHER, X-Powered-By, X-Requested-With"
  Header set   Access-Control-Allow-Methods       "CONNECT, DEBUG, DELETE, DONE, GET, HEAD, HTTP, HTTP/0.9, HTTP/1.0, HTTP/1.1, HTTP/2, OPTIONS, ORIGIN, ORIGINS, PATCH, POST, PUT, QUIC, REST, SESSION, SHOULD, SPDY, TRACE, TRACK"
  Header set   Access-Control-Allow-Credentials   "true"

  Header set DNT "0"
  Header set Accept-Ranges "bytes"
  Header set Vary "Accept-Encoding"
  Header set X-UA-Compatible "IE=edge,chrome=1"
  Header set X-Frame-Options "SAMEORIGIN"
  Header set X-Content-Type-Options "nosniff"
  Header set X-Xss-Protection "1; mode=block"
</IfModule>

Câu hỏi thường gặp:

  • Tại sao Access-Control-Allow-Headers, Access-Control-Expose-Headers,Access-Control-Allow-Methods giá trị này là siêu lâu?

    Những tiêu đề đó không hỗ trợ *cú pháp, vì vậy tôi đã thu thập các tiêu đề phổ biến nhất (và kỳ lạ) trên khắp web, ở nhiều định dạng # 1 # 2 # 3 (và tôi sẽ cập nhật danh sách theo thời gian)

  • Tại sao bạn sử dụng Header unset ______cú pháp?

    Máy chủ GoDaddy (mà trang web của tôi được lưu trữ trên ..) có một lỗi kỳ lạ trong đó nếu tiêu đề đã được đặt, giá trị trước đó sẽ kết hợp với giá trị hiện có .. (thay vì thay thế nó) theo cách này, tôi "xóa trước" các giá trị hiện có (thực sự chỉ là một giải pháp nhanh chóng & & bẩn )

  • Tôi sử dụng 'nguyên trạng' có an toàn không?

    Chà .. hầu hết câu trả lời sẽ là .htaccessnó đang giới hạn tiêu đề cho các tập lệnh (PHP, HTML, ...) và tài nguyên (.JPG, .JS, .CSS) được phân phát từ "thư mục"-vị trí sau. Bạn có thể tùy ý loại bỏ các Access-Control-Allow-Methodsdòng. Ngoài ra Connection, Time-Zone, Keep-AliveDNT, Accept-Ranges, Vary, X-UA-Compatible, X-Frame-Options, X-Content-Type-OptionsX-Xss-Protectionchỉ là một gợi ý tôi đang sử dụng cho tuyến dịch vụ của tôi .. cảm thấy tự do để loại bỏ những quá ...

lấy từ bình luận của tôi ở trên


Điều này chắc chắn đã cứu mạng tôi. Tôi đang sử dụng nhà cung cấp CDN, với CORS được bật và tôi cũng đã cho phép nó trong trang web của mình Access-Control-Allow-Origin "*"nhưng không có gì hoạt động cho đến khi tôi sử dụng cái này. Ngay cả nhà cung cấp CDN cũng không có câu trả lời cho chúng tôi. Tôi chạy trang web trong Siteground , có lẽ, với tư cách là GoDaddy , trước tiên tôi bắt buộc phải hủy đặt mọi thứ.
Ignacio Bustos

Bài viết xuất sắc, cái này sẽ được đưa lên đầu trang này.
CommonKnowledge

1
Trong trường hợp cụ thể của tôi, tôi đã phải gỡ bỏ từ Access-Control-Allow-Methodstất cả các phương pháp này: HTTP / 0.9, HTTP / 1.0, HTTP / 1.1, HTTP / 2
umbe1987

HTTP / 2 có phải là một 'Phương thức' hợp lệ không? Nâng cấp từ HTTP / 1.1 lên 2 có hoạt động như vậy hay không? Nếu tôi nhìn vào đây: sookocheff.com/post/networking/how-does-http-2-work, phần HTTP / ... được cho là ở vị trí thứ ba, không phải đầu tiên, nơi Phương thức được đặt.
Henk Poley

Có thể để hỗ trợ HTTP / 2.0, bạn cần thêm phương thức 'PRI'?
Henk Poley

17

Tôi thấy rằng Access-Control-Allow-Headers: * chỉ nên đặt cho yêu cầu OPTIONS. Nếu bạn trả lại nó cho yêu cầu POST thì trình duyệt sẽ hủy yêu cầu (ít nhất là cho chrome)

Mã PHP sau phù hợp với tôi

// Allow CORS
if (isset($_SERVER['HTTP_ORIGIN'])) {
    header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header('Access-Control-Allow-Credentials: true');    
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
}   
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    header("Access-Control-Allow-Headers: *");
}

Tôi đã tìm thấy những câu hỏi tương tự với một số câu trả lời gây hiểu lầm:

  • Chuỗi máy chủ nói rằng đây là lỗi 2 năm của chrome: Access-Control-Allow-Headers không khớp với localhost. Sai: Tôi có thể sử dụng CORS cho máy chủ cục bộ của mình với Đăng bình thường
  • Access-Control-Allow-Headerskhông chấp nhận các ký tự đại diện. Cũng sai, ký tự đại diện hoạt động với tôi (tôi chỉ thử nghiệm với Chrome)

Điều này khiến tôi mất nửa ngày để tìm ra vấn đề.

Viết mã vui vẻ


2
Ký tự đại diện ("Access-Control-Allow-Headers: *") không hoạt động đối với tôi, trên Safari 7.0.4.
Tsuneo Yoshioka

Tôi nhận thấy rằng cài đặt Access-Control-Allow-Headers hoạt động cho POST trong Phiên bản Chrome 40.0.2214.111 m.
Derek Greer

3
Điều này dường như không đúng ..... Các spec không cho phép *trên Access-Control-Allow-Headersngay cả đối OPTIONS.
Pacerier

1

Trích dẫn từ ông,

Tiêu đề Access-Control-Allow-Headers không cho phép các ký tự đại diện. Nó phải khớp chính xác: http://www.w3.org/TR/cors/#access-control-allow-headers-response-header .

Vì vậy, đây là giải pháp php của tôi.

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  $headers=getallheaders();
  @$ACRH=$headers["Access-Control-Request-Headers"];
  header("Access-Control-Allow-Headers: $ACRH");
}

1
Trên thực tế, tại sao không đơn giảnheader('Access-Control-Allow-Headers: ' . $_SERVER['HTTP_ACCESS_CONTROL_ALLOW_HEADERS']);
Pacerier

0

đây là câu thần chú cho nginx, bên trong một

location / {
    # Simple requests
    if ($request_method ~* "(GET|POST)") {
      add_header "Access-Control-Allow-Origin"  *;
    }

    # Preflighted requests
    if ($request_method = OPTIONS ) {
      add_header "Access-Control-Allow-Origin"  *;
      add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
      add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
    }

}
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.