Reputation: 47
I met an issue that the JSON string output to HTTP client was truncated near to close tag.
An example,
a. expect to see - ... ... "last_update":"2014-06-10 20:46:38","garden_id":"1"}],"message":null}
b. actually it is - ... ..."last_update":"2014-06-10 20:46:38","garden_id":"1"}],"message":nul
The last two characaters were truncated for some reason!!!
I tried both Postman on Chrome and curl on a console, all the same output. So looks not a browser specific issue. The JSON string in my application comes from a PHP json_encode on an associative array. The PHP code is using CodeIgniter framework running on Apache. I tried to write the json string into a file before http output, the file content is 100% correct. So it is not a json encoding issue in PHP.
The PHP is pretty straightforward. I have build below array (namely $finaldata) from database query
{
"success": true,
"data": [
{
"file_id": "1",
"title": "xxx",
"create_date": "2014-05-18 21:30:19",
"auditor": "1",
"status": "1",
"last_updater": null,
"last_update": "2014-06-10 20:43:14",
"garden_id": "1"
},
{
"file_id": "2",
"title": "yyy",
"create_date": "2014-05-18 21:30:19",
"auditor": "1",
"status": "1",
"last_updater": null,
"last_update": "2014-06-10 20:43:14",
"garden_id": "1"
}
],
"message": null
}
the "data" has a sub array and it could be a long array depends on database records. Then the variable $finaldata is passed to a output function that has below general logic:
header('Content-Type: '.$this->_supported_formats[$this->response->format]);
$output = $this->format->factory($finaldata)->{'to_'.$this->response->format}();
header('Content-Length: ' . strlen($output));
The output function is built by a RESTful library from https://github.com/philsturgeon/codeigniter-restserver. In this context, it equals to
header('Content-Type: Application/json');
$output = json_encode($finaldata);
But I found an interesting thing that the issue only happened if the string length exceeds 8K. And when I append a random string like "ZZZ" to the JSON string before HTTP response, the issue was gone. I don't know the reason behind. It is not a correct hack because I could not prove 8K is a real threshold though.
Has anyone met such issue before? Any suggestion or comments are appreciated.
Upvotes: 1
Views: 4748
Reputation: 1
In my issue, I enable gzip in nginx,and append application/json
to the field of gzip_types. Then, I set a header when make a request with Guzzle. It looks like
if (! isset($parameters['headers'])) {
$parameters['headers']['Accept-Encoding'] = 'gzip';
}
Upvotes: 0
Reputation: 5889
I think you send the data in UTF-8
charset so try to change this lines
header('Content-Type: '.$this->_supported_formats[$this->response->format]);
header('Content-Length: ' . strlen($output));
into this one
header('Content-Type: '.$this->_supported_formats[$this->response->format] . '; charset=utf-8');
header('Content-Length: ' . mb_strlen($output));
If this doesn't work just don't send the Content-Length
header at all. This header is "only useful" if you send a file to the browser (as a download).
Upvotes: 1