Tôi đã thiết lập ứng dụng web ASP.NET bắt đầu bằng mẫu MVC 4 / Web API. Có vẻ như mọi thứ đang hoạt động rất tốt - không có vấn đề gì mà tôi biết. Tôi đã sử dụng Chrome và Firefox để truy cập trang web. Tôi đã thử nghiệm bằng cách sử dụng Fiddler và tất cả các phản hồi dường như là về tiền.
Vì vậy, bây giờ tôi tiến hành viết một Test.aspx đơn giản để sử dụng API Web mới này. Các phần liên quan của kịch bản:
<script type="text/javascript">
$(function () {
$.ajax({
url: "http://mywebapidomain.com/api/user",
type: "GET",
contentType: "json",
success: function (data) {
$.each(data, function (index, item) {
....
});
}
);
},
failure: function (result) {
alert(result.d);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("An error occurred, please try again. " + textStatus);
}
});
});
</script>
Điều này tạo ra một tiêu đề YÊU CẦU:
OPTIONS http://host.mywebapidomain.com/api/user HTTP/1.1
Host: host.mywebapidomain.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://mywebapidomain.com
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive
Như vậy, API Web trả về một phương pháp 405 Không được phép.
HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 30 Sep 2013 13:28:12 GMT
Content-Length: 96
<Error><Message>The requested resource does not support http method 'OPTIONS'.</Message></Error>
Tôi hiểu rằng động từ OPTIONS không được kết nối trong bộ điều khiển API Web theo mặc định ... Vì vậy, tôi đã đặt mã sau trong UserController.cs của mình:
// OPTIONS http-verb handler
public HttpResponseMessage OptionsUser()
{
var response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
return response;
}
... và điều này đã loại bỏ lỗi 405 Method Not Allowed, nhưng phản hồi hoàn toàn trống - không có dữ liệu nào được trả lại:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 30 Sep 2013 12:56:21 GMT
Content-Length: 0
Phải có thêm logic ... Tôi không biết làm thế nào để viết mã đúng phương thức Tùy chọn hoặc liệu bộ điều khiển có phải là nơi thích hợp để đặt mã hay không. Kỳ lạ (đối với tôi) là trang Web API phản hồi chính xác khi được xem từ Firefox hoặc Chrome, nhưng lệnh gọi .ajax ở trên lại xảy ra lỗi. Làm cách nào để xử lý việc kiểm tra "preflight" trong mã .ajax? Có lẽ tôi nên giải quyết vấn đề này theo logic .ajax của phía khách hàng? Hoặc, nếu đây là sự cố ở phía máy chủ do không xử lý động từ OPTIONS.
Có ai giúp được không? Đây hẳn là một vấn đề rất phổ biến và tôi xin lỗi nếu nó được giải đáp ở đây. Tôi đã tìm kiếm nhưng không tìm thấy bất kỳ câu trả lời nào hữu ích.
CẬP NHẬT IMHO, đây là vấn đề phía máy khách và liên quan đến mã Ajax JQuery ở trên. Tôi nói điều này vì Fiddler không hiển thị bất kỳ tiêu đề lỗi 405 nào khi tôi truy cập mywebapidomain / api / user từ trình duyệt web. Nơi duy nhất tôi có thể lặp lại sự cố này là từ lệnh gọi .ajax () trong JQuery. Ngoài ra, lệnh gọi Ajax giống hệt ở trên hoạt động tốt khi chạy trên máy chủ (cùng một miền).
Tôi tìm thấy một bài đăng khác: Yêu cầu AJAX nguyên mẫu được gửi dưới dạng TÙY CHỌN chứ không phải GET; dẫn đến lỗi 501 dường như có liên quan, nhưng tôi đã mày mò các đề xuất của họ nhưng không thành công. Rõ ràng, JQuery được mã hóa để nếu một yêu cầu Ajax là miền chéo (của tôi là) thì nó sẽ thêm một vài tiêu đề kích hoạt tiêu đề OPTIONS bằng cách nào đó.
'X-Requested-With': 'XMLHttpRequest',
'X-Prototype-Version': Prototype.Version,
Có vẻ như cần có một giải pháp tốt hơn là sửa đổi mã lõi trong JQuery ...
Câu trả lời được cung cấp bên dưới giả định đây là sự cố phía máy chủ. Có thể, tôi đoán vậy, nhưng tôi nghiêng về phía khách hàng và việc gọi cho một nhà cung cấp dịch vụ lưu trữ sẽ không giúp ích được gì.