使用Site B控制器获取Site A的JSON数据时返回Null结果
问题解决:Site B调用Site A API返回Null的排查与修复
核心问题
Site A的/eon/auth/check/login接口通过浏览器可正常返回JSON数据,但Site B使用Laravel Http客户端(或Guzzle)调用时返回Null,无法获取数据进行后续条件判断。
代码回顾
Site A 代码
routes/web.php
Route::get('/eon/auth/check/login', [ApiController::class, 'checkLogin'] );
app/Http/Controllers/Api/ApiController.php
namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\RateLimiter; use Illuminate\Support\Str; class ApiController extends Controller { public function checkLogin(Request $request){ $username = 'admin'; $token = 'xadasd12324'; $user = User::where('username', $username)->first(); // 注意:此处直接return导致后续代码永远不会执行 return response()->json([ 'username' => $username, 'token' => $token, 'user' => $user->first_name ]); // 以下代码无法到达,若需启用需调整return位置 if($oauth_user){ RateLimiter::clear($this->throttleKey($username)); return response()->json([ 'status_code' => 200, 'message' => 'Success', ]); }else{ RateLimiter::hit($this->throttleKey($username), 3600); return response()->json([ 'status_code' => 401, 'message' => 'Unauthorized2', ]); } } private function throttleKey($username) { return Str::lower(request('username')); } private function checkTooManyFailedAttempts($username) { if (! RateLimiter::tooManyAttempts($this->throttleKey($username), 50)) { return; } abort(403, 'IP address banned. Too many login attempts.'); } }
Site B 代码
routes/web.php
Route::get('/eon/oauth/', [ApiController::class, 'oAuth']);
app/Http/Controllers/Api/ApiController.php
namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; class ApiController extends Controller { public function oAuth(Request $request){ $username = $request->u; $token = $request->id; dd($this->checkAuthToken($token, $username)); } private function checkAuthToken($token, $username){ // 注意:此处URL路径错误,与Site A路由不匹配 $result = Http::get('http://site-a.local:8080/one/auth/check/login'); $data = json_decode($result->body(), true); return $data; } }
排查与修复步骤
1. 修正请求URL路径(最关键问题)
Site B中请求的URL是/one/auth/check/login,但Site A的路由是/eon/auth/check/login,路径不匹配导致请求返回404,最终json_decode返回Null。修改Site B的请求URL:
// 修正后的URL $result = Http::get('http://site-a.local:8080/eon/auth/check/login');
2. 调试请求状态与响应内容
在调用接口时,先打印请求状态码和原始响应,确认请求是否成功:
private function checkAuthToken($token, $username){ $result = Http::get('http://site-a.local:8080/eon/auth/check/login'); // 调试用:查看状态码和响应内容 dd($result->status(), $result->body()); $data = json_decode($result->body(), true); return $data; }
- 若状态码为200:说明请求成功,再检查JSON格式是否有效
- 若状态码为404:确认URL路径、Site A服务端口是否正确
- 若状态码为500:Site A接口内部报错,需排查Site A的代码逻辑
3. 处理JSON解码错误
如果响应不是有效的JSON,json_decode会返回Null,添加错误处理:
private function checkAuthToken($token, $username){ $result = Http::get('http://site-a.local:8080/eon/auth/check/login'); if (!$result->successful()) { return ['error' => 'Request failed', 'status' => $result->status()]; } $data = json_decode($result->body(), true); if (json_last_error() !== JSON_ERROR_NONE) { return ['error' => 'Invalid JSON response', 'raw_response' => $result->body()]; } return $data; }
4. 检查Site A服务可用性
- 确保Site A在
http://site-a.local:8080正常运行,浏览器能访问不代表服务器内部调用可通,检查本地防火墙、端口占用情况 - 确认Site A的
.env配置中APP_URL是否与请求地址一致,若Site A强制HTTPS但请求用HTTP,会导致跳转或错误
5. 优化Site A接口逻辑(可选)
Site A的checkLogin方法中,开头直接return导致后续代码无法执行,若需启用oauth验证逻辑,需调整代码顺序:
public function checkLogin(Request $request){ $username = 'admin'; $token = 'xadasd12324'; $user = User::where('username', $username)->first(); // 先执行oauth判断逻辑,再返回结果 if($oauth_user){ RateLimiter::clear($this->throttleKey($username)); return response()->json([ 'status_code' => 200, 'message' => 'Success', 'username' => $username, 'token' => $token, 'user' => $user->first_name ]); }else{ RateLimiter::hit($this->throttleKey($username), 3600); return response()->json([ 'status_code' => 401, 'message' => 'Unauthorized2', ]); } }
修复后的数据使用示例
在Site B中获取到数据后,可进行条件判断:
public function oAuth(Request $request){ $username = $request->u; $token = $request->id; $authData = $this->checkAuthToken($token, $username); if(isset($authData['status_code']) && $authData['status_code'] === 200){ // 验证成功逻辑 dd('验证通过', $authData); }else{ // 验证失败逻辑 dd('验证失败', $authData['message'] ?? '未知错误'); } }
内容的提问来源于stack exchange,提问作者Joneeel
相关产品推荐
相关产品推荐

