PHP后端ssh2_connect返回503 React Router接口返回index.html
提前感谢您的帮助。
我需要从远程服务器获取所有目录及其对应内容,因此在与React应用同级目录下部署了PHP后端服务,目录结构可参考截图:foldersTreeajax.php文件中存放了所有API服务,其余服务均可正常访问,唯独用于拉取远程服务器目录的SSH服务运行异常,对应代码如下:
case 'ssh': $port = 22; $reponse='hello'; $connection = ssh2_connect($host, 22); if(!$connection) die("Connection failed");
调用该服务时始终返回React应用的index.html内容,而非预期返回的hello,返回内容示例如下:
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <title></title> <script defer src="/static/js/bundle.js"></script> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>
初步排查方向:
- 代理配置异常
ssh2_connect修改了代理配置- React路由优先级覆盖了后端路径
但同文件下的其他服务均可正常访问。
当前访问React页面的地址为:http://localhost:3000/,访问SSH服务的地址为:http://localhost:3000/root/backend/json/ssh,寻求问题排查指引。
以下为完整代码与问题复现流程:
环境配置
本地使用MAMP搭建服务器,服务运行在80端口,无额外特殊配置。.htaccess文件配置如下:
ErrorDocument 404 /page-non-trouvee.html Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "GET,PUT,POST,DELETE" Header set Access-Control-Allow-Headers "Content-Type, Authorization" Options FollowSymlinks RewriteEngine on RewriteCond %{REQUEST_URI}::$1 ^(.?/)(.)::\2$ RewriteRule ^(.*)$ - [E=BASE:%1] RewriteRule ^$ %{ENV:BASE}accueil/ [L,R=301] RewriteRule ^([a-z,A-Z,0-9,-]*)/$ %{ENV:BASE}index.php?target=$1 [L,QSA] RewriteRule ^json/([a-zA-Z]*)/$ %{ENV:BASE}index.php?target=json&action=$1 [L,QSA]
后端代码
index.php代码如下:
try{ if(!isset($_GET['target'])){ $_GET['target']=''; } switch($_GET['target']){ case 'json': require './controllers/ajax.php'; break; } }catch (Exception $e) { echo 'Exception reçue : ', $e->getMessage(), "\n"; }
index.php调用的ajax.php代码如下:
switch($_GET['action']){ case 'getAllUsers': require './controllers/userController.php'; break; // 其余接口逻辑省略 case 'ssh': $host = "待连接的远程主机地址"; $port = 22; $reponse='hello'; $connection = ssh2_connect($host, 22); if(!$connection) die("Connection failed"); break; } if(empty($json)) $json = json_encode($reponse,JSON_UNESCAPED_UNICODE); require('./views/json.phtml');
最终返回响应的json.phtml代码如下:
header("Content-Type: application/json"); echo $json;
前端代码
使用npx create-react-app命令创建React应用,所有前端文件存放在frontend目录,目录结构可参考截图:FrontendFolder。使用react router v6管理路由。index.js代码如下:
import React from "react"; import ReactDOM from "react-dom"; import { BrowserRouter, Route, Routes} from 'react-router-dom'; import './index.css'; import { App } from "./routes/App"; import { Provider } from "react-redux"; import store from './app/store'; import { StyledEngineProvider } from "@mui/material"; ReactDOM.render( <React.StrictMode> <BrowserRouter> <Provider store={store}> <StyledEngineProvider injectFirst> <Routes> <Route path="/*" element={<App />} /> </Routes> </StyledEngineProvider> </Provider> </BrowserRouter> </React.StrictMode>, document.getElementById("root") );
在frontend目录执行npm start启动React应用。
复现步骤
- 使用Postman测试服务,访问
http://localhost:3000/fps/root/backend/json/getAllUsers可正常返回数据库中的用户数据,符合预期。 - 访问SSH服务地址
http://localhost:3000/fps/root/backend/json/ssh时,返回React的index.html页面,index.html存放位置可参考截图:index.html folder location,返回内容如下:
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Configurateur produits FPS " /> <title></title> <script defer src="/static/js/bundle.js"></script> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>
而非ajax.php预期返回的hello。
已验证现象
- 注释
ajax.php中$connection = ssh2_connect($host, 22);代码行后,接口可正常返回hello,只要保留该行就会返回上述index.html文件。 - 在controllers目录手动将
ajax.php的action设置为ssh,命令行执行php ajax.php可正常获取返回结果。 - 初步疑似React或React Router触发了重定向,但无法定位修复方案。
怀疑是React Router的历史路由回退问题:手动访问或刷新非根路径URL时,请求会被兜底转发到React的index.html,即ssh2_connect执行出错时触发了该回退逻辑。
确认存在上述路由回退问题,根本原因为PHP执行$connection = ssh2_connect($host, 22);时执行失败,返回503错误,之前该错误未被.htaccess捕获。配置错误捕获规则后,Postman访问该接口直接返回无详细信息的503错误,但命令行下执行该脚本仍可正常运行。
内容的提问来源于stack exchange,提问作者Lissam

