Response::json() 发送 html 而不是 json

Posted

技术标签:

【中文标题】Response::json() 发送 html 而不是 json【英文标题】:Response::json() sending html instead of json 【发布时间】:2014-11-11 10:40:08 【问题描述】:

使用 Laravel 4,在一个控制器中使用 return Response::json(array('foo' => 'bar')) 将返回实际的 application/json,而在另一个控制器中,对于另一个操作,它将返回 text/html。这两个动作都是通过 Ajax 调用的。

faulty controller中,我尝试用这个sn-p强制内容类型:

[...]

$response = Response::json($data);
$response->header('Content-Type', 'application/json');
$response->header('Content-Foo', 'Bar'); // test if additional headers are really set
Log::info($response);
return $response;

...而 工作控制器 返回正确的 Json 响应:

return Response::json($data);

在两者中,$data 都是一个数组(经过测试)。

记录的响应来自故障控制器:

HTTP/1.0 200 OK
Cache-Control: no-cache
Content-Foo:   Bar
Content-Type:  application/json
Date:          Wed, 17 Sep 2014 10:55:03 GMT

收到的响应(在 Firebug / DevTools 中)是:

Connection  Keep-Alive
Content-Type    text/html
Date    Wed, 17 Sep 2014 10:55:03 GMT
Keep-Alive  timeout=5, max=93
Server  Apache/2.2.25 (Unix) mod_ssl/2.2.25 OpenSSL/0.9.8y DAV/2 php/5.5.3
Transfer-Encoding   chunked
X-Powered-By    PHP/5.5.3

我尝试在错误的控制器操作开始时直接返回Response::json(array('foo' => 'bar')),但它仍然以text/html 发送响应。

我想知道为什么内容类型会无缘无故地从application/json 切换到text/html?为什么收到的响应中没有模拟标头?

-- 编辑--

问题似乎出在验证器周围。

public function faultyAction()

    if(!Request::ajax()) App::abort(405);

    $validator = Validator::make(
        array('trackfile' => Input::file('trackfile')),
        array('trackfile' => 'required|audio')); // audio is a custom validator

    if($validator->fails())
    
        Log::info('validation failed!');
        return Response::json(array('code' => 1, 'message' => 'File validation has failed.'));
     
    else
    
        Log::info('validation passed!');
        return Response::json(array('code' => 0, 'filename' => 'test'));
    

...在验证通过时返回text/html响应。

public function faultyAction()

    if(!Request::ajax()) App::abort(405);

    $validator = Validator::make(
        array('trackfile' => Input::file('trackfile')),
        array('trackfile' => 'required|audio')); // audio is a custom validator

    return Response::json(array('code' => 0, 'filename' => 'test'));

...返回application/json

如何根据在代码中调用的位置返回具有不同内容类型的相同响应?

它可能来自$validator->fails()(即使似乎没有改变标题或在 Laravel 的Validator.php 代码中打印某些内容)?

【问题讨论】:

您是否在某处显示了请求的响应?如果您有错误,则可能会显示错误而不是您的期望。在这种情况下,PHP 将 Content-Type 标头覆盖为 text/html 请重新检查您提供给故障控制器的 $data 内容。 @Maskime 这是一个 XHR,所以我在 Firebug 中得到了响应。在将响应发送回之前,我在 Laravel 中记录它,然后在 Firebug 中得到它(参见两个响应)。 @justrohu 我用 $data 替换了我的原始数据以供阅读,但是实际的数据数组是原始传递给Response::json() 所以我认为问题不在于这个。 我编辑了帖子,添加了新信息和测试。 在控制器中返回响应对象之前测试内容类型。如果没问题,这意味着在返回后发生了一些变化,可能是您的 routes.php 中针对该路由的后过滤器。 【参考方案1】:

嗨,基本上使用带有数据数组作为参数的 Response::json() 就足够了。 再定义 Content-type 头是没用的,Response::json 应该默认设置正确。

我现在正在我的项目上创建 json 响应,到目前为止一切正常。 只是为了清楚错误的控制器返回带有错误内容类型标头的好值,对吗? 您可以仅使用 Response::json 再试一次吗,您能说出您使用的是哪个确切的 laravel 版本吗?

您好,我正在根据您的回复编辑我的第一个答案: 你应该测试这样的东西:

$json = json_encode($yourArray);

//先用var_dump()或者Log::info()检查$json变量,看看是否有空间问题。然后您可以创建响应。

$response = 响应::make($json, 200);

$response->header('Content-Type', 'application/json');

返回$响应;

希望对你有帮助...

【讨论】:

是的,它应该可以工作——它适用于一个控制器,但不是第二个。这就是为什么我试图强制使用内容类型。我尝试在错误的控制器操作开始时直接返回Response::json(array('foo' => 'bar')),但它仍然以text/html 发送响应,并且Laravel 没有记录任何错误。框架版本为4.2.9 我想我找到了问题所在,但不知道为什么会这样。在第一篇文章中查看我的编辑。

以上是关于Response::json() 发送 html 而不是 json的主要内容,如果未能解决你的问题,请参考以下文章

如何使用“pymysql”打印发送到 mySQL 的查询?

Python 爬虫 返回json内容

python requests库中的post详解

获取 response.json() 和 response.status

Laravel 响应::json 失败

json response.json