2012-03-08 33 views
5

Tôi đang cố gắng thiết lập Chia sẻ tài nguyên chéo đơn giản bằng cách sử dụng jQuery (1.7.1) hỗ trợ ajax trên máy khách và máy chủ python (django) được phục vụ apache. Theo tất cả các hướng dẫn Tôi đã đọc tiêu đề của tôi được thiết lập một cách chính xác, nhưng tôi tiếp tục nhận được lỗi sau:CORS Access-Control-Allow-Origin mặc dù tiêu đề chính xác

XMLHttpRequest cannot load http://myexternaldomain.com/get_data . Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.

Tiêu đề là tôi đang cố gắng (Tôi không chắc chắn nó thậm chí là nhận được qua trình duyệt) gửi là:

Request URL:http://myexternaldomain.com/get_data 
Accept:application/json, text/javascript, */*; q=0.01 
Origin:http://localhost:8080 
Referer:http://localhost:8080/static/js/test-zetta.html 
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.66 Safari/535.11 

Các mã javascript là

var request = $.ajax({ 
     url : "http://myexternaldomain.com/get_data", 
     type : "POST", 
     dataType : "json", 
     crossDomain : true 
    }); 

Lưu ý rằng origin được thiết lập một cách chính xác. Các máy chủ bổ sung thêm tiêu đề Access-Control-Allow-Origin = * sử dụng mã python sau

def process_response(self, response): 
    if response.has_header('Access-Control-Allow-Origin'): 
      return response 

    response['Access-Control-Allow-Origin'] = '*' 
    return response 

def get_orders(request): 
    """ Tell worker what to do """ 
    response_data = {} 
    response_data['action'] = 'probe' 
    response = process_response(HttpResponse(json.dumps(response_data), mimetype="application/json")) 
    return response 

Nếu tôi ghé thăm địa chỉ trực tiếp, dường như để khẳng định rằng tiêu đề đang được thiết lập một cách chính xác

Access-Control-Allow-Origin:* 
Content-Type:application/json 
Date:Thu, 08 Mar 2012 05:06:25 GMT 
Server:Apache/2.2.20 (Ubuntu) 
Transfer-Encoding:chunked 

Tuy nhiên trong lĩnh vực chéo đặt nó luôn thất bại (đã thử cả chrome và firefox). Tôi đã cố gắng thực hiện các mã chính xác như mỗi câu trả lời được lựa chọn để this câu hỏi, nhưng gặp phải lỗi tương tự

Cập nhật

Tôi khá chắc chắn rằng vấn đề là phía máy chủ, như tôi đã được quản lý để có được các cuộc gọi ajax của tôi hoạt động với một máy chủ CORS công khai khác nhau. Khi tôi so sánh các tiêu đề quay lại từ máy chủ công cộng này và các tiêu đề được trả lại từ máy chủ của tôi (khi tôi thử nghiệm từ cùng một miền), tôi không thể thấy bất kỳ khác biệt lớn nào có thể giải thích sự khác biệt (xem bên dưới).

Một sự tinh tế mà tôi đã loại trừ, điều có thể hoặc quan trọng là miền thực tế là miền amazon của nhiều tên miền phụ. Địa chỉ thực tế http://ec2-23-20-27-108.compute-1.amazonaws.com/get_orders, vui lòng thăm dò để xem tôi đang làm gì sai.

Từ máy chủ Công

Access-Control-Allow-Origin:* 
Connection:Keep-Alive 
Content-Encoding:gzip 
Content-Length:622 
Content-Type:text/html 
Date:Thu, 08 Mar 2012 15:33:20 GMT 
Keep-Alive:timeout=15, max=99 
Server:Apache/2.2.14 (Ubuntu) 
Vary:Accept-Encoding 
X-Powered-By:Perl/5.8.7, PHP/4.4.0 

Từ máy chủ của tôi - (không hoạt động cross domain)

Access-Control-Allow-Origin:* 
Content-Encoding:gzip 
Content-Type:text/plain 
Date:Thu, 08 Mar 2012 15:32:24 GMT 
Server:Apache/2.2.20 (Ubuntu) 
Transfer-Encoding:chunked 
Vary:Accept-Encoding 
+1

Tôi đã thử, trong quá khứ, cho phép CORS cho dữ liệu Json và không bao giờ thành công. CORS có thể bị lung lay như thế. Bạn sẽ tốt hơn rất nhiều khi chỉ trả lại JSON-P. – xbonez

+0

Bạn chỉ đăng các tiêu đề từ trao đổi _final_ giữa máy chủ từ xa và máy khách cục bộ. Nếu bạn nhìn vào sự trao đổi hoàn chỉnh, tôi chắc chắn bạn sẽ thấy một yêu cầu OPTIONS cùng với một phản hồi có chứa các tiêu đề Access-Control-Allow-Methods và Access-Control-Allow-Headers. –

Trả lời

5

Vì vậy, tôi đã bị đánh lừa bởi phản hồi khi truy cập URL và thực tế vấn đề là khi thực hiện yêu cầu ajax, tôi nhận được 403 (chỉ tiết lộ trong firefox không chrome) lỗi do bảo vệ csrf.

+1

Oh người đàn ông, cảm ơn rất nhiều. Tôi đã có trình bao bọc 'enable_cors' của mình xung quanh trình bao bọc' csrf_exempt' của mình, cần thiết để đảo ngược chúng. Tôi như thế, WTF ... – orokusaki

5

Bạn cần phải thực hiện một "pre-flighted" request và response vì bạn tình trạng được tính là một yêu cầu "not so simple". CORS cơ bản, chỉ yêu cầu tiêu đề Gốc, chỉ có thể có các loại nội dung "application/x-www-form-urlencoded", "multipart/form-data" và "text/plain". Vì bạn trả về "application/json", bạn không đáp ứng yêu cầu này.

Tôi không biết gì về Django, nhưng tôi thấy dễ dàng hơn khi triển khai hỗ trợ CORS bên ngoài ứng dụng của tôi thông qua việc sử dụng số Tomcat filter. Có vẻ như bạn có thể do the same thing với Django.

2013-08-11: Dường như repo GitHub không còn với chúng tôi nữa.Tuy nhiên, gói Django vẫn có sẵn tại https://pypi.python.org/pypi/django-cors/0.1

+0

Khá chắc chắn trình duyệt được cho là sẽ xử lý yêu cầu preflight .... ít nhất Chrome cũng vậy. –

+0

Nhưng máy chủ phải nhận ra nó. Kịch bản của anh ta chỉ đáp ứng các yêu cầu cơ bản bằng cách thêm tiêu đề Gốc vào mọi yêu cầu. –

+0

Tôi đã thử làm cho yêu cầu đơn giản, bằng cách làm cho dữ liệu của tôi thành một chuỗi đơn giản, mong muốn văn bản thuần trong cuộc gọi $ .ajax và trả về mimetype = 'text/plain' trong python, nhưng vẫn gặp lỗi tương tự. – zenna

2

Tôi đã sử dụng thư viện tuyệt vời django-cors-headers và cũng gặp sự cố này. Đối với tôi, giải pháp là thêm 'accept-encoding' vào CORS_ALLOW_HEADERS tuple mặc định.

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