简体   繁体   English

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

[英]Response::json() sending html instead of json

Using Laravel 4, return Response::json(array('foo' => 'bar')) used in one controller will return actual application/json , whereas in another controller, for another action, it will return text/html .使用 Laravel 4, return Response::json(array('foo' => 'bar'))在一个 controller 中使用将返回实际的application/json ,而在另一个 controller 中,对于另一个操作,它将返回text/html Both actions are called via Ajax.这两个操作都是通过 Ajax 调用的。

In the faulty controller , I tried to force the content-type with this snippet:错误的 controller中,我试图用这个片段强制内容类型:

[...]

$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;

... while working controller returns correct Json response with: ...在工作时 controller返回正确的 Json 响应:

return Response::json($data);

In both, $data is an array (tested).在两者中, $data是一个数组(已测试)。

Logged response from the faulty controller is:来自故障 controller 的记录响应是:

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

But received response (in Firebug / DevTools) is:收到的响应(在 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

I tried to directly return Response::json(array('foo' => 'bar')) at the beginning of the faulty controller action but it still sends the response as text/html .我试图在错误的 controller 操作开始时直接返回Response::json(array('foo' => 'bar'))但它仍然以text/html形式发送响应。

I would like to know why would the content-type switch from application/json to text/html for no reason?我想知道为什么内容类型会无故从application/json切换到text/html And why the mock header isn't in the received response?为什么模拟 header 不在收到的响应中?

-- EDIT -- - 编辑 -

The problem seems to be located around the validator.问题似乎出在验证器周围。

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'));
    }
}

... returns text/html response while validation passed . ...在验证通过时返回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'));
}

... returns application/json . ...返回application/json

How comes the same response is returned with different content-type depending on where it is called in the code?为什么会根据在代码中的调用位置返回具有不同内容类型的相同响应?

May it come from $validator->fails() (even if nothing seems to alter the headers or to print something in the Laravel's Validator.php code)?它可能来自$validator->fails() (即使似乎没有任何东西改变标头或在 Laravel 的Validator.php代码中打印一些东西)?

Hi basically using Response::json() with an array of data as parameter is enough. 嗨,基本上,将Response :: json()与数据数组作为参数就足够了。 Defining again the Content-type header is useless, Response::json is supposed to set it right by default. 再次定义Content-type头是没有用的,Response :: json应该默认将其设置为正确。

I'm creating json responses on my project right now and so far it went fine. 我现在在我的项目上创建json响应,到目前为止一切正常。 Just to be clear the faulty controller returns the good value with a wrong content-type header, right ? 只是为了清楚起见,有故障的控制器使用错误的内容类型标头返回了正确的值,对吗? Can you try again using just Response::json and can you tell which exact laravel version are you using ? 您可以仅使用Response :: json再试一次,也可以告诉您使用哪个确切的laravel版本吗?

Hi again i'm editing my first answer based on your replies : you should test something like this : 再次嗨,我正在根据您的回复编辑我的第一个答案:您应该测试以下内容:

$json = json_encode($yourArray); $ json = json_encode($ yourArray);

// first check the $json variable with var_dump() oro Log::info() to see if you have the space problem. //首先使用var_dump()或Log :: info()检查$ json变量,看看是否存在空间问题。 Then you can create the response. 然后,您可以创建响应。

$response = Response::make($json, 200); $ response = Response :: make($ json,200);

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

return $response; 返回$ response;

Hope it helps... 希望能帮助到你...

It may not be the case for OP, but this is a best search result for json response sent as text/html . OP 可能不是这种情况,但这是对作为 text/html 发送的 json 响应的最佳搜索结果。 I just spent considerable amount of time debugging this issue in Laravel 9 with php 8.2我只是花了相当多的时间在 Laravel 9 和 php 8.2 中调试这个问题

One possible reason for wrong content type is hidden somewhere in php magic goo.错误内容类型的一个可能原因隐藏在 php magic goo 中的某处。 In another words, how it handles sending response headers.换句话说,它如何处理发送响应标头。

If you have whitespace anywhere before or after php opening or closing tag, respectively, the headers will be sent and you cant modify them anymore.如果您分别在 php 开始或结束标记之前或之后的任何地方有空格,则将发送标头并且您不能再修改它们。 This is why it is recommended to not use php closing tag in multi file applications, but this does not help for whitespace before opening tag:这就是为什么建议不要在多文件应用程序中使用 php 结束标记,但这对打开标记前的空白没有帮助:


 <?php

Now if your framework, like Laravel, checks with headers_sent() , before modifying headers for you, the result is, drumm roll: text/html, with no errors anywhere.现在,如果您的框架(如 Laravel)使用headers_sent()检查,则在为您修改标头之前,结果是 drumm roll: text/html,没有任何错误。

To identify the problem, try setting headers yourself, with header() , somewhere at the end of call stack.要确定问题,请尝试使用header()自己在调用堆栈末尾的某处设置标头。 It should then fail and tell you in which file the headers are already sent.然后它应该会失败并告诉您标头已发送到哪个文件中。 For me the culprit was hidden in one of the lang files.对我来说,罪魁祸首隐藏在其中一个 lang 文件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM