Azure Linux Web App中React POST请求超时及WebSocket连接失败问题
Azure Linux Web App向Azure SQL数据库添加数据时的连接超时问题
错误信息
DataAdd.js:26 POST https://website.azurewebsites.net:5000/add-data net::ERR_CONNECTION_TIMED_OUT
Error: TypeError: Failed to fetch at handleSubmit (DataAdd.js:26:1) at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1) at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1) at invokeGuardedCallback (react-dom.development.js:4277:1) at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1) at executeDispatch (react-dom.development.js:9041:1) at processDispatchQueueItemsInOrder (react-dom.development.js:9073:1) at processDispatchQueue (react-dom.development.js:9086:1) at dispatchEventsForPlugins (react-dom.development.js:9097:1) at react-dom.development.js:9288:1
WebSocketClient.js:13 WebSocket connection to 'wss://website.azurewebsites.net:8080/ws' failed:
相关代码
DataAdd.js
import React, { useState } from 'react'; import './DataAdd.css'; const DataAdd = () => { const [formData, setFormData] = useState({ description: '', Nimi: '', Syntymäaika: '', Rotu: '', Sukupuoli: '', Rekisterinumero: '', Omistaja: '' }); const handleChange = (e) => { const { name, value } = e.target; setFormData({ ...formData, [name]: value }); }; const handleSubmit = async (e) => { e.preventDefault(); try { const response = await fetch('https://website.azurewebsites.net:5000/add-data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }); if (response.ok) { alert('Data added successfully'); setFormData({ description: '', Nimi: '', Syntymäaika: '', Rotu: '', Sukupuoli: '', Rekisterinumero: '', Omistaja: '' }); } else { alert('Error adding data'); } } catch (error) { console.error('Error:', error); alert('Error adding data'); } }; return ( <div> <h1>Add Data</h1> <form onSubmit={handleSubmit}> <div> <label>Description</label> <input type="text" name="description" value={formData.description} onChange={handleChange} required /> </div> <div> <label>Nimi</label> <input type="text" name="Nimi" value={formData.Nimi} onChange={handleChange} required /> </div> <div> <label>Syntymäaika</label> <input type="date" name="Syntymäaika" value={formData.Syntymäaika} onChange={handleChange} required /> </div> <div> <label>Rotu</label> <input type="text" name="Rotu" value={formData.Rotu} onChange={handleChange} required /> </div> <div> <label>Sukupuoli</label> <input type="text" name="Sukupuoli" value={formData.Sukupuoli} onChange={handleChange} required /> </div> <div> <label>Rekisterinumero</label> <input type="text" name="Rekisterinumero" value={formData.Rekisterinumero} onChange={handleChange} required /> </div> <div> <label>Omistaja</label> <input type="text" name="Omistaja" value={formData.Omistaja} onChange={handleChange} required /> </div> <button type="submit">Add Data</button> </form> </div> ); }; export default DataAdd;
server.js
require('dotenv').config(); const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const sql = require('mssql'); const app = express(); const port = process.env.REACT_APP_AZURE_SERVER_PORT; const config = { user: process.env.REACT_APP_AZURE_SQL_USER, password: process.env.REACT_APP_AZURE_SQL_PASSWORD, server: process.env.REACT_APP_AZURE_SQL_SERVER, port: parseInt(process.env.REACT_APP_AZURE_SQL_PORT, 10), database: process.env.REACT_APP_AZURE_SQL_DATABASE, authentication: { type: 'default' }, options: { encrypt: true, requestTimeout: 60000, connectionTimeout: 30000 } }; // Add CORS middleware app.use(cors({ origin: 'https://website.azurewebsites.net', // Adjust based on your frontend URL methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', preflightContinue: false, optionsSuccessStatus: 204 })); // Add body parser middleware app.use(express.json()); async function connectWithRetry() { let retries = 5; while (retries) { try { const pool = await sql.connect(config); return pool; } catch (err) { console.log(`Connection failed, retries left: ${retries - 1}`); console.error(err); retries -= 1; await new Promise(res => setTimeout(res, 5000)); // wait for 5 seconds before retrying } } throw new Error('Could not connect to the database after multiple attempts'); } connectWithRetry().then(pool => { console.log("Connected to the database"); app.post('/add-data', async (req, res) => { try { console.log('Received request:', req.body); const { description, Nimi, Syntymäaika, Rotu, Sukupuoli, Rekisterinumero, Omistaja } = req.body; console.log('Connecting to database...'); const result = await pool.request() .input('description', sql.NVarChar, description) .input('Nimi', sql.NVarChar, Nimi) .input('Syntymäaika', sql.Date, Syntymäaika) .input('Rotu', sql.NVarChar, Rotu) .input('Sukupuoli', sql.NVarChar, Sukupuoli) .input('Rekisterinumero', sql.NVarChar, Rekisterinumero) .input('Omistaja', sql.NVarChar, Omistaja) .query(` INSERT INTO dbo.hevoset (description, Nimi, Syntymäaika, Rotu, Sukupuoli, Rekisterinumero, Omistaja) VALUES (@description, @Nimi, @Syntymäaika, @Rotu, @Sukupuoli, @Rekisterinumero, @Omistaja) `); console.log('Data added:', result); res.status(200).send('Data added successfully'); } catch (err) { console.error('Error adding data:', err); res.status(500).send('Error adding data'); } }); app.listen(port, () => { console.log(`Server running on port ${port}`); }); }).catch(err => { console.error('Database connection failed: ', err.message); });
已尝试操作
- 确认服务器正常运行,日志显示监听正确端口
- 核对React请求的URL和端口与服务器一致
- 配置CORS允许客户端URL请求
- 通过curl/Postman测试端点正常
- 本地环境下数据库连接和数据添加功能正常
- 添加日志捕获请求和错误
环境信息
- 客户端:托管在Azure的React Web App(Linux)
- 服务器:Azure SQL Server
- 数据库:Azure SQL Database
排查与解决方案
Azure Web App端口配置修正
Azure Linux Web App仅默认开放80/443端口,自定义端口无法直接对外访问:- 进入Azure门户的目标Web App,在「配置」→「常规设置」中添加应用程序设置
PORT,值为你的服务端口(如5000) - 前端请求去掉端口,直接使用
https://website.azurewebsites.net/add-data,Azure会自动将80/443的请求转发到内部配置的端口
- 进入Azure门户的目标Web App,在「配置」→「常规设置」中添加应用程序设置
数据库防火墙规则检查
- 进入Azure SQL Server的「防火墙和虚拟网络」设置,添加Web App的所有出站IP地址,或勾选「允许Azure服务和资源访问此服务器」
- 确认Web App的网络配置未限制到Azure SQL默认端口1433的出站流量
环境变量同步
本地.env文件不会自动同步到Azure,需手动在Web App的「配置」→「应用程序设置」中添加所有REACT_APP_*开头的环境变量,包括数据库连接信息和服务端口WebSocket问题处理
- 若无需WebSocket功能,排查代码中是否有多余的WebSocket初始化逻辑
- 若需要WebSocket,在Web App的「配置」→「常规设置」中将「WebSocket」设为开启状态
内容的提问来源于stack exchange,提问作者WaterProofComputer
相关产品推荐
相关产品推荐

