Laravel:将 JSON 响应编码为 UTF-8
Laravel: Encode JSON responses in UTF-8
我想将我的 API 的 JSON 响应编码为 UTF-8,但每次我做出响应时我不想这样做:
return response()->json($res,200,['Content-type'=>'application/json;charset=utf-8'],JSON_UNESCAPED_UNICODE);
所以我考虑为所有 API 路由制作一个中间件,handle(...)
函数是这样的:
public function handle($request, Closure $next) {
$response = $next($request);
$response->header('Content-type','application/json; charset=utf-8');
return $next($request);
}
问题是它不起作用,我的回复 Content-type
header 仍然是 application/json
而不是 application/json; charset=utf-8
;可能是因为 json(...)
函数已经设置了 Content-type
header 而我无法覆盖它。
我该怎么办?
感谢您的帮助。
它就在文档中,您想使用 after 中间件(以下代码来自我的脑海,它应该可以工作):
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
public function handle($request, Closure $next)
{
/** @var array $data */ // you need to return array from controller
$data = $next($request);
return response()->json($data, 200, ['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'],
JSON_UNESCAPED_UNICODE);
}
}
通过上述方法,我们可以发现两个反模式:
- 在中间件中制作响应(你应该在控制器中完成)
- 使用未转义的 JSON 响应,Laravel 创建者将转义响应设为默认值,为什么要更改它?!
删除中间件并仅使用控制器
将以下代码放入app/Http/Controller.php
protected function jsonResponse($data, $code = 200)
{
return response()->json($data, $code,
['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'], JSON_UNESCAPED_UNICODE);
}
在由基本控制器扩展的任何控制器中 (app/Http/Controller.php) 您可以使用 $this->jsonResponse($data);
专业人士是如何做到的
他们使用 eloquent resources or if there is more going on fractal is the way to go (in Laravel use spatie wrapper - https://github.com/spatie/laravel-fractal).
在您的 JsonResource
class 中添加:
/**
* Customize the outgoing response for the resource.
*
* @param \Illuminate\Http\Request
* @param \Illuminate\Http\Response
* @return void
*/
public function withResponse($request, $response)
{
$charset = $request->header('Accept-Charset', 'utf-8');
if ($charset === 'utf-8') {
$response->header('Charset', 'utf-8');
$response->header('Content-Type','application/json; charset=utf-8');
$response->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
// Alternative: iso-8859-1 which will be encoded by default using json escaping.
}
我想将我的 API 的 JSON 响应编码为 UTF-8,但每次我做出响应时我不想这样做:
return response()->json($res,200,['Content-type'=>'application/json;charset=utf-8'],JSON_UNESCAPED_UNICODE);
所以我考虑为所有 API 路由制作一个中间件,handle(...)
函数是这样的:
public function handle($request, Closure $next) {
$response = $next($request);
$response->header('Content-type','application/json; charset=utf-8');
return $next($request);
}
问题是它不起作用,我的回复 Content-type
header 仍然是 application/json
而不是 application/json; charset=utf-8
;可能是因为 json(...)
函数已经设置了 Content-type
header 而我无法覆盖它。
我该怎么办?
感谢您的帮助。
它就在文档中,您想使用 after 中间件(以下代码来自我的脑海,它应该可以工作):
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
public function handle($request, Closure $next)
{
/** @var array $data */ // you need to return array from controller
$data = $next($request);
return response()->json($data, 200, ['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'],
JSON_UNESCAPED_UNICODE);
}
}
通过上述方法,我们可以发现两个反模式:
- 在中间件中制作响应(你应该在控制器中完成)
- 使用未转义的 JSON 响应,Laravel 创建者将转义响应设为默认值,为什么要更改它?!
删除中间件并仅使用控制器
将以下代码放入app/Http/Controller.php
protected function jsonResponse($data, $code = 200)
{
return response()->json($data, $code,
['Content-Type' => 'application/json;charset=UTF-8', 'Charset' => 'utf-8'], JSON_UNESCAPED_UNICODE);
}
在由基本控制器扩展的任何控制器中 (app/Http/Controller.php) 您可以使用 $this->jsonResponse($data);
专业人士是如何做到的
他们使用 eloquent resources or if there is more going on fractal is the way to go (in Laravel use spatie wrapper - https://github.com/spatie/laravel-fractal).
在您的 JsonResource
class 中添加:
/**
* Customize the outgoing response for the resource.
*
* @param \Illuminate\Http\Request
* @param \Illuminate\Http\Response
* @return void
*/
public function withResponse($request, $response)
{
$charset = $request->header('Accept-Charset', 'utf-8');
if ($charset === 'utf-8') {
$response->header('Charset', 'utf-8');
$response->header('Content-Type','application/json; charset=utf-8');
$response->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
// Alternative: iso-8859-1 which will be encoded by default using json escaping.
}