Search K
Appearance
Appearance
📊 SEO元描述:2024年最新HTTP状态码教程,详解200 404 500等常见状态码、状态码分类、错误处理最佳实践。包含完整代码示例,适合前端开发者快速掌握HTTP状态码处理。
核心关键词:HTTP状态码2024、200 404 500状态码、HTTP错误处理、状态码分类、前端错误处理
长尾关键词:HTTP状态码有哪些、404错误怎么处理、500错误是什么、HTTP状态码分类、前端状态码处理
通过本节HTTP状态码详解,你将系统性掌握:
HTTP状态码是什么?HTTP状态码是服务器对客户端请求的响应状态标识,由三位数字组成,也是Web应用错误处理和用户体验优化的重要依据。
💡 学习建议:理解状态码的分类和含义,是构建健壮Web应用的基础
HTTP状态码按照第一位数字分为五大类:
// 🎉 HTTP状态码分类详解
class HTTPStatusCodesDemo {
constructor() {
this.explainStatusCodeCategories();
this.demonstrateCommonStatusCodes();
this.createStatusCodeHandler();
}
explainStatusCodeCategories() {
console.log('=== HTTP状态码分类体系 ===');
const statusCodeCategories = {
'1xx': {
name: '信息响应',
description: '请求已接收,继续处理',
characteristics: [
'临时响应',
'需要客户端继续操作',
'很少在实际应用中使用'
],
examples: {
100: 'Continue - 继续请求',
101: 'Switching Protocols - 切换协议',
102: 'Processing - 处理中'
}
},
'2xx': {
name: '成功响应',
description: '请求已成功被服务器接收、理解并接受',
characteristics: [
'操作成功完成',
'客户端请求正确',
'最常见的成功状态'
],
examples: {
200: 'OK - 请求成功',
201: 'Created - 资源创建成功',
202: 'Accepted - 请求已接受',
204: 'No Content - 无内容返回'
}
},
'3xx': {
name: '重定向',
description: '需要进一步操作以完成请求',
characteristics: [
'资源位置发生变化',
'需要客户端采取进一步行动',
'可能需要用户干预'
],
examples: {
301: 'Moved Permanently - 永久重定向',
302: 'Found - 临时重定向',
304: 'Not Modified - 未修改',
307: 'Temporary Redirect - 临时重定向'
}
},
'4xx': {
name: '客户端错误',
description: '客户端请求有错误',
characteristics: [
'请求语法错误',
'客户端权限问题',
'资源不存在'
],
examples: {
400: 'Bad Request - 请求错误',
401: 'Unauthorized - 未授权',
403: 'Forbidden - 禁止访问',
404: 'Not Found - 资源不存在',
422: 'Unprocessable Entity - 无法处理的实体'
}
},
'5xx': {
name: '服务器错误',
description: '服务器在处理请求时发生错误',
characteristics: [
'服务器内部错误',
'服务器配置问题',
'服务器过载'
],
examples: {
500: 'Internal Server Error - 服务器内部错误',
502: 'Bad Gateway - 网关错误',
503: 'Service Unavailable - 服务不可用',
504: 'Gateway Timeout - 网关超时'
}
}
};
Object.entries(statusCodeCategories).forEach(([category, info]) => {
console.log(`${category} - ${info.name}:`);
console.log(` 描述: ${info.description}`);
console.log(` 特征: ${info.characteristics.join(', ')}`);
console.log(` 示例:`);
Object.entries(info.examples).forEach(([code, desc]) => {
console.log(` ${code}: ${desc}`);
});
console.log('');
});
}
demonstrateCommonStatusCodes() {
console.log('=== 常见状态码详解 ===');
// 最常见的状态码详细说明
const commonStatusCodes = {
// 成功状态码
200: {
name: 'OK',
description: '请求成功,服务器返回请求的数据',
useCases: ['GET请求成功', 'POST请求处理完成', '一般性成功响应'],
example: {
request: 'GET /api/users/123',
response: {
status: 200,
data: { id: 123, name: 'John Doe' }
}
}
},
201: {
name: 'Created',
description: '请求成功并创建了新资源',
useCases: ['POST创建资源成功', 'PUT创建新资源'],
example: {
request: 'POST /api/users',
response: {
status: 201,
data: { id: 124, name: 'Jane Doe' },
location: '/api/users/124'
}
}
},
// 重定向状态码
301: {
name: 'Moved Permanently',
description: '资源永久移动到新位置',
useCases: ['网站迁移', 'URL结构调整', 'SEO优化'],
example: {
request: 'GET /old-page',
response: {
status: 301,
location: '/new-page'
}
}
},
304: {
name: 'Not Modified',
description: '资源未修改,可使用缓存版本',
useCases: ['条件请求', '缓存验证', '性能优化'],
example: {
request: 'GET /api/data (If-None-Match: "etag123")',
response: {
status: 304,
headers: { 'ETag': '"etag123"' }
}
}
},
// 客户端错误状态码
400: {
name: 'Bad Request',
description: '请求语法错误或参数无效',
useCases: ['参数格式错误', '必需参数缺失', '请求体格式错误'],
example: {
request: 'POST /api/users (缺少必需字段)',
response: {
status: 400,
error: {
message: '请求参数错误',
details: ['name字段是必需的', 'email格式无效']
}
}
}
},
401: {
name: 'Unauthorized',
description: '请求需要身份验证',
useCases: ['未提供认证信息', '认证信息无效', 'Token过期'],
example: {
request: 'GET /api/profile (无Authorization头)',
response: {
status: 401,
error: { message: '需要身份验证' },
headers: { 'WWW-Authenticate': 'Bearer' }
}
}
},
403: {
name: 'Forbidden',
description: '服务器理解请求但拒绝执行',
useCases: ['权限不足', '资源被保护', '访问被限制'],
example: {
request: 'DELETE /api/admin/users/123 (普通用户)',
response: {
status: 403,
error: { message: '权限不足,无法执行此操作' }
}
}
},
404: {
name: 'Not Found',
description: '请求的资源不存在',
useCases: ['URL路径错误', '资源已删除', 'API端点不存在'],
example: {
request: 'GET /api/users/999',
response: {
status: 404,
error: { message: '用户不存在' }
}
}
},
// 服务器错误状态码
500: {
name: 'Internal Server Error',
description: '服务器内部错误',
useCases: ['代码异常', '数据库连接失败', '未处理的异常'],
example: {
request: 'GET /api/users',
response: {
status: 500,
error: { message: '服务器内部错误,请稍后重试' }
}
}
},
502: {
name: 'Bad Gateway',
description: '网关或代理服务器收到无效响应',
useCases: ['上游服务器错误', '负载均衡器问题', '代理配置错误'],
example: {
request: 'GET /api/external-service',
response: {
status: 502,
error: { message: '上游服务暂时不可用' }
}
}
},
503: {
name: 'Service Unavailable',
description: '服务暂时不可用',
useCases: ['服务器维护', '过载保护', '临时关闭'],
example: {
request: 'GET /api/users',
response: {
status: 503,
error: { message: '服务正在维护中' },
headers: { 'Retry-After': '3600' }
}
}
}
};
Object.entries(commonStatusCodes).forEach(([code, info]) => {
console.log(`${code} ${info.name}:`);
console.log(` 描述: ${info.description}`);
console.log(` 使用场景: ${info.useCases.join(', ')}`);
console.log(` 示例:`, info.example);
console.log('');
});
}
createStatusCodeHandler() {
console.log('=== 状态码处理器 ===');
// 创建状态码处理器类
class StatusCodeHandler {
constructor() {
this.handlers = new Map();
this.setupDefaultHandlers();
}
// 设置默认处理器
setupDefaultHandlers() {
// 成功处理器
this.addHandler('2xx', (response, data) => {
console.log('✅ 请求成功:', response.status);
return { success: true, data, status: response.status };
});
// 重定向处理器
this.addHandler('3xx', (response, data) => {
console.log('🔄 重定向:', response.status);
const location = response.headers.get('location');
return {
success: true,
redirect: true,
location,
status: response.status
};
});
// 客户端错误处理器
this.addHandler('4xx', (response, data) => {
console.log('⚠️ 客户端错误:', response.status);
return {
success: false,
error: data || '客户端请求错误',
status: response.status,
type: 'client_error'
};
});
// 服务器错误处理器
this.addHandler('5xx', (response, data) => {
console.log('❌ 服务器错误:', response.status);
return {
success: false,
error: data || '服务器内部错误',
status: response.status,
type: 'server_error',
retry: true
};
});
// 特定状态码处理器
this.addHandler(401, (response, data) => {
console.log('🔐 需要身份验证');
// 可以在这里触发登录流程
return {
success: false,
error: '需要身份验证',
status: 401,
requiresAuth: true
};
});
this.addHandler(404, (response, data) => {
console.log('🔍 资源不存在');
return {
success: false,
error: '请求的资源不存在',
status: 404,
notFound: true
};
});
}
// 添加状态码处理器
addHandler(statusCode, handler) {
this.handlers.set(statusCode, handler);
}
// 处理响应
async handleResponse(response) {
let data;
try {
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
data = await response.json();
} else {
data = await response.text();
}
} catch (error) {
console.warn('响应体解析失败:', error);
data = null;
}
// 查找特定状态码处理器
if (this.handlers.has(response.status)) {
return this.handlers.get(response.status)(response, data);
}
// 查找分类处理器
const category = `${Math.floor(response.status / 100)}xx`;
if (this.handlers.has(category)) {
return this.handlers.get(category)(response, data);
}
// 默认处理
return {
success: response.ok,
data,
status: response.status,
error: response.ok ? null : `HTTP ${response.status}: ${response.statusText}`
};
}
// 发送请求并处理状态码
async request(url, options = {}) {
try {
console.log(`发送请求: ${options.method || 'GET'} ${url}`);
const response = await fetch(url, options);
return await this.handleResponse(response);
} catch (error) {
console.error('网络请求失败:', error);
return {
success: false,
error: '网络连接失败',
networkError: true
};
}
}
}
// 使用状态码处理器
const handler = new StatusCodeHandler();
// 演示不同状态码的处理
this.demonstrateStatusCodeHandling(handler);
}
async demonstrateStatusCodeHandling(handler) {
console.log('=== 状态码处理演示 ===');
// 测试不同的状态码响应
const testCases = [
{
name: '成功请求',
url: 'https://jsonplaceholder.typicode.com/posts/1',
options: { method: 'GET' }
},
{
name: '资源不存在',
url: 'https://jsonplaceholder.typicode.com/posts/999999',
options: { method: 'GET' }
},
{
name: '创建资源',
url: 'https://jsonplaceholder.typicode.com/posts',
options: {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'Test', body: 'Content', userId: 1 })
}
}
];
// 依次测试各种情况
for (const testCase of testCases) {
console.log(`\n测试: ${testCase.name}`);
try {
const result = await handler.request(testCase.url, testCase.options);
console.log('处理结果:', result);
} catch (error) {
console.error('测试失败:', error);
}
// 添加延迟避免请求过快
await new Promise(resolve => setTimeout(resolve, 500));
}
}
}
// 创建HTTP状态码演示实例
const statusCodesDemo = new HTTPStatusCodesDemo();2xx状态码表示请求成功处理:
// 🎉 2xx成功状态码处理
class SuccessStatusCodesDemo {
constructor() {
this.demonstrate2xxStatusCodes();
this.createSuccessHandler();
}
demonstrate2xxStatusCodes() {
console.log('=== 2xx成功状态码详解 ===');
const successCodes = {
200: {
name: 'OK',
description: '标准成功响应',
scenarios: [
'GET请求成功获取数据',
'POST请求成功处理(不创建资源)',
'PUT请求成功更新资源',
'DELETE请求成功删除资源'
],
bestPractices: [
'包含请求的数据',
'设置适当的缓存头',
'提供完整的响应信息'
]
},
201: {
name: 'Created',
description: '资源创建成功',
scenarios: [
'POST请求创建新资源',
'PUT请求创建新资源(如果不存在)'
],
bestPractices: [
'返回创建的资源数据',
'提供Location头指向新资源',
'包含资源的唯一标识符'
]
},
202: {
name: 'Accepted',
description: '请求已接受,但处理未完成',
scenarios: [
'异步处理任务',
'批量操作',
'长时间运行的操作'
],
bestPractices: [
'提供任务状态查询URL',
'估算处理时间',
'提供进度跟踪机制'
]
},
204: {
name: 'No Content',
description: '请求成功但无内容返回',
scenarios: [
'DELETE请求成功',
'PUT请求更新成功(无需返回数据)',
'配置更新操作'
],
bestPractices: [
'确保没有响应体',
'设置适当的缓存策略',
'提供操作确认信息(通过头部)'
]
}
};
Object.entries(successCodes).forEach(([code, info]) => {
console.log(`${code} ${info.name}:`);
console.log(` 描述: ${info.description}`);
console.log(` 使用场景: ${info.scenarios.join(', ')}`);
console.log(` 最佳实践: ${info.bestPractices.join(', ')}`);
});
}
createSuccessHandler() {
console.log('=== 成功状态码处理器 ===');
class SuccessResponseHandler {
// 处理200 OK响应
handle200(response, data) {
return {
success: true,
data: data,
status: 200,
message: '请求成功'
};
}
// 处理201 Created响应
handle201(response, data) {
const location = response.headers.get('location');
return {
success: true,
data: data,
status: 201,
message: '资源创建成功',
location: location,
resourceId: this.extractResourceId(location)
};
}
// 处理202 Accepted响应
handle202(response, data) {
return {
success: true,
data: data,
status: 202,
message: '请求已接受,正在处理',
async: true,
statusUrl: data?.statusUrl || null
};
}
// 处理204 No Content响应
handle204(response) {
return {
success: true,
status: 204,
message: '操作成功完成',
noContent: true
};
}
// 从Location头提取资源ID
extractResourceId(location) {
if (!location) return null;
const matches = location.match(/\/(\d+)$/);
return matches ? matches[1] : null;
}
// 统一处理成功响应
handleSuccess(response, data) {
switch (response.status) {
case 200:
return this.handle200(response, data);
case 201:
return this.handle201(response, data);
case 202:
return this.handle202(response, data);
case 204:
return this.handle204(response);
default:
return {
success: true,
data: data,
status: response.status,
message: '请求成功'
};
}
}
}
// 演示成功状态码处理
const successHandler = new SuccessResponseHandler();
// 模拟不同的成功响应
const mockResponses = [
{ status: 200, headers: new Map(), data: { id: 1, name: 'Test' } },
{ status: 201, headers: new Map([['location', '/api/users/123']]), data: { id: 123, name: 'New User' } },
{ status: 202, headers: new Map(), data: { statusUrl: '/api/tasks/456' } },
{ status: 204, headers: new Map(), data: null }
];
mockResponses.forEach(mockResponse => {
const result = successHandler.handleSuccess(mockResponse, mockResponse.data);
console.log(`状态码 ${mockResponse.status} 处理结果:`, result);
});
}
}
// 创建成功状态码演示实例
const successDemo = new SuccessStatusCodesDemo();4xx状态码表示客户端请求错误,需要提供清晰的错误信息:
// 🎉 4xx客户端错误处理
class ClientErrorStatusCodesDemo {
constructor() {
this.demonstrate4xxStatusCodes();
this.createErrorHandler();
this.showUserFriendlyErrorHandling();
}
demonstrate4xxStatusCodes() {
console.log('=== 4xx客户端错误状态码详解 ===');
const clientErrorCodes = {
400: {
name: 'Bad Request',
causes: ['参数格式错误', '必需参数缺失', '请求体格式无效'],
userMessage: '请求参数有误,请检查输入内容',
developerActions: ['验证请求参数', '检查API文档', '确认数据格式']
},
401: {
name: 'Unauthorized',
causes: ['未提供认证信息', 'Token无效或过期', '认证格式错误'],
userMessage: '请先登录后再试',
developerActions: ['检查认证头', '刷新Token', '重新登录']
},
403: {
name: 'Forbidden',
causes: ['权限不足', '账户被禁用', '资源访问受限'],
userMessage: '您没有权限执行此操作',
developerActions: ['检查用户权限', '联系管理员', '确认资源访问策略']
},
404: {
name: 'Not Found',
causes: ['URL路径错误', '资源已删除', 'API端点不存在'],
userMessage: '请求的内容不存在',
developerActions: ['检查URL路径', '确认资源存在', '查看API文档']
},
409: {
name: 'Conflict',
causes: ['资源冲突', '并发修改', '业务规则冲突'],
userMessage: '操作冲突,请刷新后重试',
developerActions: ['处理并发冲突', '检查业务逻辑', '实现乐观锁']
},
422: {
name: 'Unprocessable Entity',
causes: ['数据验证失败', '业务规则不满足', '关联数据缺失'],
userMessage: '提交的数据不符合要求',
developerActions: ['检查验证规则', '确认业务逻辑', '提供详细错误信息']
},
429: {
name: 'Too Many Requests',
causes: ['请求频率过高', '超出配额限制', '触发限流'],
userMessage: '请求过于频繁,请稍后再试',
developerActions: ['实现请求限流', '添加重试机制', '优化请求频率']
}
};
Object.entries(clientErrorCodes).forEach(([code, info]) => {
console.log(`${code} ${info.name}:`);
console.log(` 常见原因: ${info.causes.join(', ')}`);
console.log(` 用户提示: ${info.userMessage}`);
console.log(` 开发者行动: ${info.developerActions.join(', ')}`);
});
}
createErrorHandler() {
console.log('=== 客户端错误处理器 ===');
class ClientErrorHandler {
constructor() {
this.errorMessages = new Map();
this.setupErrorMessages();
}
setupErrorMessages() {
// 设置用户友好的错误消息
this.errorMessages.set(400, {
title: '请求错误',
message: '请求参数有误,请检查输入内容',
action: '检查输入',
icon: '⚠️'
});
this.errorMessages.set(401, {
title: '需要登录',
message: '请先登录后再试',
action: '立即登录',
icon: '🔐'
});
this.errorMessages.set(403, {
title: '权限不足',
message: '您没有权限执行此操作',
action: '联系管理员',
icon: '🚫'
});
this.errorMessages.set(404, {
title: '内容不存在',
message: '请求的内容不存在或已被删除',
action: '返回首页',
icon: '🔍'
});
this.errorMessages.set(409, {
title: '操作冲突',
message: '操作冲突,请刷新页面后重试',
action: '刷新页面',
icon: '⚡'
});
this.errorMessages.set(422, {
title: '数据验证失败',
message: '提交的数据不符合要求',
action: '修改数据',
icon: '📝'
});
this.errorMessages.set(429, {
title: '请求过于频繁',
message: '请求过于频繁,请稍后再试',
action: '稍后重试',
icon: '⏰'
});
}
// 处理客户端错误
handleClientError(response, errorData) {
const statusCode = response.status;
const errorInfo = this.errorMessages.get(statusCode) || {
title: '请求错误',
message: '客户端请求出现错误',
action: '重试',
icon: '❌'
};
// 构建错误响应
const errorResponse = {
success: false,
status: statusCode,
type: 'client_error',
error: {
...errorInfo,
details: this.extractErrorDetails(errorData),
timestamp: new Date().toISOString(),
requestId: this.generateRequestId()
}
};
// 特殊处理
switch (statusCode) {
case 401:
errorResponse.requiresAuth = true;
break;
case 403:
errorResponse.insufficientPermissions = true;
break;
case 404:
errorResponse.notFound = true;
break;
case 429:
errorResponse.retryAfter = this.getRetryAfter(response);
break;
}
return errorResponse;
}
// 提取错误详情
extractErrorDetails(errorData) {
if (!errorData) return null;
if (typeof errorData === 'string') {
return { message: errorData };
}
if (errorData.errors && Array.isArray(errorData.errors)) {
return { validationErrors: errorData.errors };
}
if (errorData.message) {
return { message: errorData.message };
}
return errorData;
}
// 获取重试时间
getRetryAfter(response) {
const retryAfter = response.headers.get('retry-after');
if (retryAfter) {
const seconds = parseInt(retryAfter);
return isNaN(seconds) ? 60 : seconds;
}
return 60; // 默认60秒
}
// 生成请求ID
generateRequestId() {
return Math.random().toString(36).substr(2, 9);
}
}
// 演示客户端错误处理
const errorHandler = new ClientErrorHandler();
// 模拟不同的客户端错误
const mockErrors = [
{ status: 400, data: { message: '缺少必需参数 name' } },
{ status: 401, data: { message: 'Token已过期' } },
{ status: 403, data: { message: '用户权限不足' } },
{ status: 404, data: { message: '用户不存在' } },
{ status: 422, data: { errors: ['邮箱格式无效', '密码长度不足'] } }
];
mockErrors.forEach(mockError => {
const mockResponse = {
status: mockError.status,
headers: new Map()
};
const result = errorHandler.handleClientError(mockResponse, mockError.data);
console.log(`状态码 ${mockError.status} 错误处理:`, result);
});
}
showUserFriendlyErrorHandling() {
console.log('=== 用户友好的错误处理 ===');
// 用户友好的错误处理组件
class UserFriendlyErrorHandler {
constructor() {
this.errorContainer = null;
this.setupErrorContainer();
}
setupErrorContainer() {
// 在实际应用中,这里会创建DOM元素
console.log('设置错误显示容器');
}
// 显示错误消息
showError(errorInfo) {
const errorDisplay = {
type: 'error',
title: errorInfo.title,
message: errorInfo.message,
action: errorInfo.action,
icon: errorInfo.icon,
timestamp: new Date().toLocaleTimeString()
};
console.log('显示用户错误:', errorDisplay);
// 在实际应用中,这里会更新UI
this.updateErrorUI(errorDisplay);
// 自动隐藏非关键错误
if (!this.isCriticalError(errorInfo)) {
setTimeout(() => {
this.hideError();
}, 5000);
}
}
// 更新错误UI
updateErrorUI(errorDisplay) {
// 模拟UI更新
console.log(`${errorDisplay.icon} ${errorDisplay.title}: ${errorDisplay.message}`);
if (errorDisplay.action) {
console.log(`建议操作: ${errorDisplay.action}`);
}
}
// 判断是否为关键错误
isCriticalError(errorInfo) {
const criticalErrors = ['需要登录', '权限不足', '内容不存在'];
return criticalErrors.includes(errorInfo.title);
}
// 隐藏错误消息
hideError() {
console.log('隐藏错误消息');
}
// 显示成功消息
showSuccess(message) {
console.log(`✅ 成功: ${message}`);
}
// 显示加载状态
showLoading(message = '加载中...') {
console.log(`⏳ ${message}`);
}
// 隐藏加载状态
hideLoading() {
console.log('隐藏加载状态');
}
}
// 演示用户友好的错误处理
const uiHandler = new UserFriendlyErrorHandler();
// 模拟不同类型的错误显示
const errorScenarios = [
{ title: '请求错误', message: '请求参数有误,请检查输入内容', action: '检查输入', icon: '⚠️' },
{ title: '需要登录', message: '请先登录后再试', action: '立即登录', icon: '🔐' },
{ title: '权限不足', message: '您没有权限执行此操作', action: '联系管理员', icon: '🚫' }
];
errorScenarios.forEach((scenario, index) => {
setTimeout(() => {
uiHandler.showError(scenario);
}, index * 1000);
});
}
}
// 创建客户端错误演示实例
const clientErrorDemo = new ClientErrorStatusCodesDemo();💼 最佳实践:正确处理HTTP状态码是构建用户友好应用的关键,要为不同状态码提供合适的用户反馈和处理策略
通过本节HTTP状态码详解的学习,你已经掌握:
A: 当请求成功创建了新资源时使用201,如POST创建用户。200用于一般的成功响应,如GET获取数据或PUT更新现有资源。
A: 401表示未认证(需要登录),403表示已认证但权限不足。401可以通过提供认证信息解决,403需要更高权限。
A: 5xx错误通常需要重试机制,记录错误日志,向用户显示友好的错误消息,并考虑降级方案或备用服务。
A: 400用于请求格式错误(如JSON格式错误),422用于请求格式正确但数据验证失败(如邮箱格式无效)。
A: 建议使用统一的错误响应结构,包含错误代码、消息、详细信息和时间戳,确保所有API端点使用相同的格式。
// 问题:不同API返回的错误格式不一致
// 解决:创建统一的错误响应格式
class UnifiedErrorResponse {
static create(status, message, details = null) {
return {
success: false,
error: {
status,
message,
details,
timestamp: new Date().toISOString(),
requestId: Math.random().toString(36).substr(2, 9)
}
};
}
static badRequest(message, validationErrors = null) {
return this.create(400, message, { validationErrors });
}
static unauthorized(message = '需要身份验证') {
return this.create(401, message);
}
static forbidden(message = '权限不足') {
return this.create(403, message);
}
static notFound(message = '资源不存在') {
return this.create(404, message);
}
static serverError(message = '服务器内部错误') {
return this.create(500, message);
}
}// 问题:网络错误或服务器错误时没有重试机制
// 解决:实现智能重试策略
class RetryableRequest {
constructor(maxRetries = 3, baseDelay = 1000) {
this.maxRetries = maxRetries;
this.baseDelay = baseDelay;
}
async request(url, options = {}) {
let lastError;
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
try {
const response = await fetch(url, options);
// 对于某些状态码不进行重试
if (!this.shouldRetry(response.status)) {
return response;
}
if (attempt === this.maxRetries) {
return response;
}
// 指数退避延迟
const delay = this.baseDelay * Math.pow(2, attempt);
await new Promise(resolve => setTimeout(resolve, delay));
} catch (error) {
lastError = error;
if (attempt === this.maxRetries) {
throw error;
}
const delay = this.baseDelay * Math.pow(2, attempt);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw lastError;
}
shouldRetry(status) {
// 只对服务器错误和某些客户端错误重试
return status >= 500 || status === 408 || status === 429;
}
}"掌握HTTP状态码是构建健壮Web应用的基础,通过正确理解和处理各种状态码,你将能够提供更好的用户体验和更可靠的应用服务!"