记一次解决前端websocket调用后台失败报404

本文记录了一次解决前端WebSocket调用后台失败,出现404错误的经历。问题出现在心跳连接上,通过检查前后端代码,发现是IDEA配置问题。在IDEA中,将websocket-api.jar的适用范围从Compile更改为Provide,解决了问题。同时,清理已编译的代码和artifacts也是关键步骤。
部署运行你感兴趣的模型镜像

正常心跳(3s一次):

失败心跳

前端:

后端:

解决方案:

我用的是idea 2020社区版,所以,是在idea里进行配置的

按快捷键ctrl + shift + alt + s 或者是点击下图中“A”处,打开窗口,将websocket-api.jar 的适用范围由Compile改为Provide,ok,解决问题。(如果是maven的话,应该是改jar的scope属性)

 

一定要记得删除掉已经编译的代码和创建的artifacts

 

 

 

 

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>好的,我现在需要解决用户的问题:前端页面请求超时后返回404的问题。用户希望找到解决方案。首先,我得理清问题的具体情况。 根据用户提供的引用,前端发送请求后,如果后台处理时间过长(比如超过60秒),前端控制台会显示请求被取消(canceled),这导致用户最终遇到404错误。可能的情况是,前端在超时后自动取消请求,而后台可能还在处理,当用户再次尝试访问时,可能资源未准备好,导致404。或者,后台处理失败,返回了404。 首先,我需要分析问题产生的原因。引用[1]提到前端请求在60秒后取消,引用[2]和[3]讨论了后台处理时间过长导致前端超时的问题,解决方案包括异步处理和轮询。引用[4]则提到请求超时的机制。用户现在遇到的是超时后返回404,这可能是由于前端在超时后重试,但资源未生成,或者后台处理失败。 可能的解决方向有几个: 1. 后台优化:减少处理时间,避免超时。但有时处理时间长是不可避免的,比如复杂计算或第三方调用。这时候需要考虑异步处理。 2. 前端处理:调整超时时间,但这可能不现实,因为用户提到的超时时间可能受浏览器或服务器配置限制。 3. 异步处理:后台接到请求后立即返回202 Accepted,并开始异步处理。前端轮询或使用WebSocket获取结果。这样前端不会长时间等待,避免超时。 4. 错误处理:前端在超时后,不直接跳转或显示404,而是提示用户处理中,并定期检查状态。 现在需要结合这些引用中的解决方案。根据引用[2],Spring Boot可以使用异步响应,比如DeferredResult或CompletableFuture,让后台立即返回,处理完成后再通知前端前端需要轮询结果,或者使用长轮询、WebSocket。 用户提到超时后返回404,可能的原因是前端在超时后重新请求了一个不存在的资源。例如,假设前端在超时后尝试获取结果,但后台还未完成处理,此时资源不存在,返回404。因此,解决方案应包括: - 后台异步处理,生成资源后存储结果,并提供状态查询接口。 - 前端在初次请求后,收到处理ID,定期查询状态,直到处理完成。 - 前端处理超时时,提示用户等待,而不是直接跳转。 另外,需要确保后台处理完成后,资源可用,避免404。例如,生成临时URL或确保资源路径正确。 可能还需要配置服务器的超时时间,但根据引用[2],异步处理是更有效的方案,因为它解耦了请求和处理,避免前端长时间等待。 总结步骤: 1. 修改后台接口为异步处理,立即返回202和任务ID。 2. 前端轮询状态接口,直到任务完成。 3. 处理完成后,前端获取结果,避免404。 4. 前端优化错误处理,超时后提示而非跳转。 5. 后台确保资源在完成后可访问,避免404。 需要检查用户的具体实现,比如前端框架(如Vue,引用[3])和后台框架(如Spring Boot,引用[2]),提供相应的代码示例。 例如,后台使用Spring Boot的DeferredResult: ```java @RestController public class AsyncController { private Map<String, DeferredResult<ResponseEntity<?>>> tasks = new ConcurrentHashMap<>(); @PostMapping("/api/task") public DeferredResult<ResponseEntity<?>> createTask() { String taskId = UUID.randomUUID().toString(); DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>(60000L); tasks.put(taskId, deferredResult); // 异步处理任务 CompletableFuture.runAsync(() -> { // 长时间处理 ResponseEntity<?> result = processTask(); deferredResult.setResult(result); tasks.remove(taskId); }); return deferredResult; } @GetMapping("/api/status/{taskId}") public ResponseEntity<?> checkStatus(@PathVariable String taskId) { if (tasks.containsKey(taskId)) { return ResponseEntity.accepted().body("处理中"); } else { return ResponseEntity.ok().body("处理完成"); } } } ``` 前端部分,使用Vue进行轮询: ```javascript async function submitTask() { try { const response = await axios.post('/api/task'); const taskId = response.data.taskId; const pollInterval = setInterval(async () => { const statusResponse = await axios.get(`/api/status/${taskId}`); if (statusResponse.data === '处理完成') { clearInterval(pollInterval); // 获取最终结果 const result = await axios.get(`/api/result/${taskId}`); // 处理结果 } }, 2000); } catch (error) { if (error.response && error.response.status === 404) { // 处理404错误,提示用户 } } } ``` 此外,前端在超时后应处理错误,而不是直接跳转。比如,使用axios的拦截器处理超时错误,显示提示信息: ```javascript axios.interceptors.response.use( response => response, error => { if (error.code === 'ECONNABORTED') { // 显示友好提示,如“处理中,请稍后查看” } return Promise.reject(error); } ); ``` 最后,确保后台在处理完成后正确存储结果,并提供访问接口,避免404。例如,处理完成后将结果存入数据库或缓存,状态接口返回完成时,前端再请求结果接口。 总结:解决方案需要前后端配合,采用异步处理加轮询机制,前端优化错误处理逻辑,后台确保资源可访问。</think>### 前端请求超时导致404错误的解决方案 #### 问题分析 当后台接口处理时间超过前端设置的超时时间(如60秒),请求会被前端主动取消(状态显示为`canceled`)[^1][^3]。此时可能出现404错误的原因包括: 1. **资源未生成**:后台仍在处理,但前端已超时并尝试访问未准备好的资源 2. **二次请求失效**:用户重复提交请求时,后台未正确处理异步任务状态 3. **错误处理缺失**:前端未正确处理超时后的状态提示 --- ### 解决方案(前后端协作) #### 一、后端改造:异步处理机制 **1. 接口拆分(Spring Boot示例)** ```java // 提交任务接口 @PostMapping("/submit") public ResponseEntity<Task> submitTask() { String taskId = UUID.randomUUID().toString(); Task task = new Task(taskId, "PROCESSING"); taskQueue.add(task); // 异步处理 CompletableFuture.runAsync(() -> { processTask(taskId); // 耗时操作 task.setStatus("COMPLETED"); }); return ResponseEntity.accepted().body(task); // 返回202状态码[^2] } // 状态查询接口 @GetMapping("/status/{taskId}") public ResponseEntity<Task> getStatus(@PathVariable String taskId) { return taskQueue.findById(taskId) .map(task -> ResponseEntity.ok(task)) .orElse(ResponseEntity.notFound().build()); } ``` **2. 关键配置** ```yaml # application.yml spring: task: execution: pool: core-size: 10 max-size: 50 ``` --- #### 二、前端优化:交互设计 **1. 请求处理改造(Vue + axios示例)** ```javascript // 提交请求时获取任务ID async submit() { try { const res = await axios.post('/submit', params, {timeout: 30000}) this.startPolling(res.data.taskId) // 开始轮询 } catch (err) { if (err.code === 'ECONNABORTED') { this.$message.warning('请求已提交,请稍后查看结果') // 超时提示而非跳转 } } } // 轮询状态 startPolling(taskId) { const timer = setInterval(async () => { const res = await axios.get(`/status/${taskId}`) if (res.data.status === 'COMPLETED') { clearInterval(timer) this.loadResult(taskId) // 获取最终结果 } }, 2000) } ``` **2. 错误拦截处理** ```javascript // 全局拦截器 axios.interceptors.response.use( response => response, error => { if (error.response?.status === 404) { return Promise.reject('操作尚未完成,请勿重复提交') } return Promise.reject(error) } ) ``` --- #### 三、架构优化建议 1. **结果缓存**:使用Redis存储处理结果,设置合理过期时间 ```java @CachePut(value = "results", key = "#taskId") public Task processTask(String taskId) { // 处理逻辑 } ``` 2. **进度反馈**:支持返回处理进度百分比而非简单状态 3. **WebSocket推送**:重要任务可采用实时推送机制 ```javascript const ws = new WebSocket(`/ws/${taskId}`) ws.onmessage = (event) => { this.progress = JSON.parse(event.data).percent } ``` --- ### 效果验证 | 阶段 | 旧方案 | 新方案 | |---------------|--------------------------|-------------------------------| | 请求提交 | 直接超时错 | 立即返回任务ID,提示"处理中" | | 处理中 | 页面卡死 | 显示进度条或状态提示 | | 处理完成 | 需要用户重新操作 | 自动刷新结果区域 | | 错误场景 | 直接显示404 | 明确提示"任务仍在处理中" | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值