2016-08-03 18 views
10

Từ những gì tôi đã đọc về CORS, tôi hiểu nó sẽ làm việc như sau:CORS: Tại sao trình duyệt của tôi không gửi yêu cầu preflight preflight?

  1. Script trên một mặt khách hàng cố gắng lấy resource từ một máy chủ với nguồn gốc khác nhau.
  2. Trình duyệt chặn yêu cầu này và trước tiên thực hiện yêu cầu preflight OPTIONS cho cùng một URL.
  3. Nếu phản ứng yêu cầu preflight này chứa tiêu đề thích hợp (ví dụ Access-Control-Allow-Origin: *), trình duyệt hiểu nó được phép gửi yêu cầu chính và hiện nó.
  4. Trả lời được trả lại cho tập lệnh khách hàng.

tôi đã thiết lập một thử nghiệm cho nó như thế này:

  • máy chủ tại Gò chấp nhận cả hai - GET và OPTIONS yêu cầu (kiểm tra sử dụng CURL) - và thiết lập Access-Control-* tiêu đề trong phản ứng
  • trang HTML đơn giản (được phục vụ bởi một máy chủ khác trên cổng khác) với tập lệnh sau trong đó ($ là viết tắt của jQuery):

    $.ajax({ 
        type: "GET", 
        crossDomain: true, 
        url: "http://local.site.com/endpoint, 
        success: function (data) { 
        alert(data); 
        }, 
        error: function (request, error) { 
        alert(error); 
        } 
    }); 
    

Khi tôi gọi phương pháp này, tuy nhiên, tôi thấy chỉ có một GET và không OPTIONS preflight yêu cầu trong tab Mạng trong cả hai - Chrome 49 và Firefox 33.

Dưới đây là chi tiết về yêu cầu GET của tôi từ Chrome:

Accept:*/* 
Accept-Encoding:gzip, deflate, sdch 
Accept-Language:en-US,en;q=0.8,ru;q=0.6 
Connection:keep-alive 
Host:local.adform.com 
Origin:http://localhost:7500 
Referer:http://localhost:7500/test-page.html 
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36 

và phản ứng tương ứng:

Access-Control-Allow-Headers:Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization 
Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT, DELETE 
Access-Control-Allow-Origin:* 
Content-Length:2 
Content-Type:text/plain; charset=utf-8 
Date:Wed, 03 Aug 2016 10:53:19 GMT 

Bất kỳ suy nghĩ về lý do tại sao (s) trình duyệt của tôi không gửi preflight yêu cầu?

+2

preflight không phải lúc nào cũng được thực hiện, ít có khả năng (nếu có?) Với GET - xem [tài liệu] (https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests) cho khi preflight được yêu cầu –

+1

Xem [this] (https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests) để biết thêm thông tin về thời điểm trình duyệt phát hành yêu cầu preflight. – robertklep

+0

@JaromandaX: Cảm ơn bạn đã nhận xét. Nếu yêu cầu preflight không phải lúc nào cũng được yêu cầu, cách (thông thường) để vượt qua chính sách "cùng nguồn gốc" là gì? Kịch bản là: chúng tôi tạo tập lệnh sẽ được tích hợp vào các trang web của bên thứ ba và sẽ gửi cho chúng tôi cookie _our_? Theo tôi hiểu, không có trình duyệt yêu cầu preflight sẽ không gửi cookie đến máy chủ của chúng tôi, đúng không? – ffriend

Trả lời

7

Như được chỉ ra bởi các nhà bình luận, với trình duyệt GET không phải lúc nào cũng gửi yêu cầu OPTIONS preflight. Nếu thực sự là cần thiết, một cách để làm cho trình duyệt gửi nó là đặt tiêu đề tùy chỉnh (ví dụ: "X-PINGOVER: pingpong" hoặc bất kỳ thứ gì). Lưu ý, máy chủ đó cũng phải cho phép tiêu đề yêu cầu này bằng cách thêm nó vào "Access-Control-Allow-Headers" tiêu đề phản hồi.


mục tiêu cơ bản của tôi là vượt qua cookie với miền a.com đến các máy chủ của a.com, nhưng từ một trang của một trang web khác (s) b.com (trường hợp sử dụng chung cho điều này là theo dõi người dùng của bạn trên các trang web bên thứ 3) . Hóa ra là gửi cookie cùng với yêu cầu nhiều hơn một chút công việc có liên quan.

Trên phía máy khách (ví dụ: trong JavaScript), bạn cần bật yêu cầu miền chéo và cho phép thông tin xác thực vượt qua. Ví dụ.các yêu cầu sau đây với jQuery làm việc cho tôi:

$.ajax({ 
    type: "GET", 
    url: "http://example.com", 
    xhrFields: { 
    withCredentials: true   // allow passing cookies 
    }, 
    crossDomain: true,    // force corss-domain request     
    success: function (data) { ... }, 
    error: function (request, error) { ... } 
}); 

On phía máy chủ người ta cần phải thiết lập 2 tiêu đề phản ứng:

  • Access-Control-Allow-Credentials: true
  • Access-Control-Allow-Origin: <requester origin>

nơi <requester origin> là giao thức + máy chủ + cổng của trang web thực hiện cuộc gọi. Lưu ý rằng, chung chung * có thể không hoạt động trong nhiều trình duyệt, do đó, máy chủ phân tích cú pháp Referer tiêu đề yêu cầu và phản hồi với nguồn gốc được phép cụ thể.

+0

Xem Tài liệu yêu cầu [MDN Preflight] (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests) để biết thêm thông tin. – styfle

+0

Điều quan trọng cần lưu ý là máy chủ của bạn có thể không mong đợi "X-PINGOVER" làm tiêu đề và có thể trả về lỗi. Để giải quyết vấn đề này, trong mã máy chủ của bạn, nơi bạn đặt giá trị của 'Access-Control-Allow-Headers', bao gồm' X-PINGOVER' – user2023861

Các vấn đề liên quan