【发布时间】:2020-07-18 11:57:07
【问题描述】:
我正在使用 jQuery 的 $.ajax 方法发送请求,并希望在请求未成功时打印 HTTP 状态代码。
当 POST/GET 请求本身因错误而失败时,一切都很好,并且可以在 error 回调中轻松打印错误。
但是,当浏览器发送预检 OPTIONS 请求并且失败(例如,由于 URL 错误而导致 404)时,回调不会打印任何有用的信息。
对于下面的示例,控制台会打印以下内容:
response: [object Object]
response.status: 0
response.statusText: error
response.responseText: undefined
status: error
error:
当我在浏览器调试器中检查网络请求时,会收到以下响应头:
HTTP/1.0 404 NOT FOUND
Content-Type: application/json
Content-Length: 130
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Vary: Origin
Server: Werkzeug/1.0.0 Python/3.6.9
Date: Mon, 06 Apr 2020 13:01:47 GMT
如何获取 404 状态代码以打印有用的错误消息?目前,我唯一能做的就是打印unknown error,这并不能说明问题实际上是404。
示例代码:
import $ from 'jquery';
$(function() {
$('#file-upload').on('change', function(e) {
e.preventDefault();
const files = $(this).prop('files');
const file = files && files.length && files[0];
const reader = new FileReader();
reader.onload = (e) => {
let encoded = e && e.target && e.target.result.toString().replace(/^data:(.*,)?/, '');
$.ajax({
type: 'POST',
url: 'http://localhost:8000/upload',
data: JSON.stringify({data: encoded}),
contentType: 'application/json',
dataType: 'json',
cache: false,
crossDomain: true,
processData: true,
success: (response) => {
console.log('success');
},
error: (response, status, error) => {
console.log("response: " + response);
console.log("response.status: " + response.status);
console.log("response.statusText: " + response.statusText);
console.log("response.responseText: " + response.responseText);
console.log("status: " + status);
console.log("error: " + error);
},
complete: () => {
$(this).val('');
},
});
};
if (file) {
reader.readAsDataURL(file);
}
});
});
【问题讨论】:
-
它不是同一个端口(@987654327@ vs.
3000)所以它不应该工作 -
我不明白,后端在 8000 上运行,前端在 3000 上运行。当后端从 GET 请求本身返回错误时,而不是从 OPTIONS 请求返回,一切正常。
-
发生 CORS 错误时,您无法访问响应。这是出于安全原因而设计的。如果您在这种情况下同时拥有客户端和服务器,只需将 CORS 标头添加到您发送的响应中
-
我同时拥有客户端和服务器,并且我确实设置了正确的 CORS 标头。但是,浏览器似乎向
/foo/bar发送了一个 OPTIONS 请求,该请求可能不存在。因此,404 会使用正确的 CORS 标头发送。但是,客户端应用程序无法读取 404,因为浏览器显然将此视为 CORS 故障,尽管事实并非如此。 -
您无法从前端代码访问 CORS 预检 OPTIONS 响应标头。浏览器不会向您的代码公开该 OPTIONS 响应。如果对预检 OPTIONS 请求的响应不是 200、204 或其他 2xx 成功代码,则预检失败并且浏览器会停在那里。因此,如果您的代码导致浏览器向 URL 发送预检请求,从而使服务器以 404 响应,那么您的其余代码将永远不会被执行——并且您的前端代码无法访问该 OPTIONS 响应的状态代码, 也不是它的响应头