Laravel 5.5+Guzzle 6转发POST请求中文编码及字段异常问题
Hey there, let's tackle this API forwarding headache you're dealing with. I've run into similar encoding and data formatting issues before, so let's break down what's going wrong and how to fix it.
Why Your Current Approaches Aren't Working
Let's start by understanding the root cause of each problem:
- Using
$request->json()->all()with Guzzle'sjsonoption: When you pass the parsed array to Guzzle'sjsonparameter, Guzzle automatically runsjson_encodeon it. By default, this encodes Chinese characters into Unicode escape sequences (\uXXXX) and can sometimes convert empty strings tonulldepending on how the external API parses incoming data. - Using
$request->getContent()as thejsonparameter: Guzzle'sjsonoption expects an array/object, not a pre-encoded JSON string. Passing raw content here will cause Guzzle to re-encode the string, resulting in escaped characters like\"instead of plain quotes. utf8_decodefor Chinese characters: This function converts UTF-8 text to ISO-8859-1 (Latin-1), which doesn't support Chinese characters—so you're guaranteed to get garbled text here. Don't use this for Chinese!
The Solutions
1. Directly Forward the Raw Request Body (No Data Modifications)
If you don't need to alter the incoming request data before forwarding, this is the most reliable approach. It sends the exact same body and headers (adjusted for Guzzle) that your Laravel app received:
use GuzzleHttp\Client; public function insert(Request $request) { $client = new Client(); $externalApiUrl = 'https://your-external-api.com/endpoint'; $response = $client->post($externalApiUrl, [ // Forward all headers except Content-Length (Guzzle will calculate this automatically) 'headers' => $request->headers->except(['Content-Length']), // Send the raw, unmodified request body 'body' => $request->getContent(), ]); // Handle the response as needed return response()->json(json_decode($response->getBody(), true)); }
This ensures Chinese characters stay in their original UTF-8 form, empty strings remain as "", and no unnecessary encoding happens.
2. Modify Data Before Forwarding (Preserve Encoding)
If you need to tweak the request data first, manually encode the array with the correct JSON options to avoid Unicode escapes and preserve empty strings:
use GuzzleHttp\Client; public function insert(Request $request) { $client = new Client(); $externalApiUrl = 'https://your-external-api.com/endpoint'; // Get the parsed request data $data = $request->json()->all(); // Make any necessary modifications to $data here // Example: $data['additional_field'] = 'some value'; $response = $client->post($externalApiUrl, [ 'headers' => [ 'Content-Type' => 'application/json', // Add any other required headers here ], // Manually encode with options to preserve UTF-8 and empty strings 'body' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION), ]); return response()->json(json_decode($response->getBody(), true)); }
The JSON_UNESCAPED_UNICODE flag keeps Chinese characters in their original form, while JSON_PRESERVE_ZERO_FRACTION ensures empty strings and numeric values are encoded correctly without being converted to null.
Quick Notes
- Always double-check the
Content-Typeheader when forwarding—make sure it's set toapplication/jsonif the external API expects JSON data. - If the external API has specific header requirements (like authentication), add those to the
headersarray in your Guzzle request.
内容的提问来源于stack exchange,提问作者Scott Fu

