4

Using PHP Zend Framework 2.0.2, I return JSON data after an AJAX call. Obviously, Internet Explorer 9 wants to download the data instead of returning it to the calling Javascript method.

Posts like this one and this one say to use Content-Type: text/plain instead of Content-Type: application/json, but how do I do this with ZF2's JsonModel? I'm new to it...

I imagine I have to set something in the setOptions() array, but what?

public function testJsonAction()
{
   $jsonResponse = new JsonModel(array('success' => false));

   $jsonResponse->setOptions(array(
         // ** Should I put something here? What? **
   ));

   return $jsonResponse;
}

I tried using these:

  $this->getResponse()->getHeaders()->addHeaderLine('Content-Type', 'text/plain');
  $this->getResponse()->getHeaders()->addHeaderLine('Content-Disposition', 'inline; filename="textdata.json"');

but it doesn't change the HTTP Content-Type in the response headers:

Key                   Value
Response              HTTP/1.1 200 OK
Content-Type          application/json
Server                Microsoft-IIS/7.5
X-Powered-By          PHP/5.3.13
Set-Cookie            ZDEDebuggerPresent=php,phtml,php3; path=/
Content-Disposition   inline; filename="textdata.json"
X-Powered-By          ASP.NET
Date                  Wed, 10 Oct 2012 13:19:42 GMT
Content-Length        17

Thanks for your help!

Community
  • 1
  • 1
dstj
  • 4,800
  • 2
  • 39
  • 61

1 Answers1

3

Because when \Zend\Mvc\MvcEvent::EVENT_RENDER event happen, the JsonStrategy will change content-type again. Source code is in

Zend\View\Strategy\JsonStrategy->injectResponse();

So in order to replace content-type into yours, you need to use EventManager to inject your custom header after JsonStrategy injected.

try below codes in your controller:

 $this->getServiceLocator()->get('Application')->getEventManager()->attach(\Zend\Mvc\MvcEvent::EVENT_RENDER, function($event){
     $event->getResponse()->getHeaders()->addHeaderLine('Content-Type', 'text/plain');
 }, -10000);
AlloVince
  • 1,655
  • 11
  • 18
  • Thanks but it did not work, it's still `application/json`. I set breakpoints in the function you mentioned and I saw it's called after the attached event is called... and after that point, the headers contains 3 times the Content-Type key. – dstj Oct 11 '12 at 02:53
  • Hi again! I tried attaching the event function to the `MvcEvent::EVENT_FINISH` event instead at it worked! Would there be any reason NOT to do that in your opinion? – dstj Oct 11 '12 at 03:02
  • Hi, actually I just test my code in ViewModel and it works, just now I tested JsonViewModel and I found that the event priority is not small enough, I adjustment it to -10000 and it works. I didnot use EVENT_FINISH because JsonStrategy change header in EVENT_RENDER, just in order to reduce the invasive. – AlloVince Oct 11 '12 at 04:09
  • Thanks! It worked. But, I did have to change `$this` for `$event` in the event function otherwise I get a `Using $this when not in object context` error... – dstj Oct 11 '12 at 16:42
  • In my development environment, use $this is ok without any warning, maybe this is related to php version, my php is 5.4.4 – AlloVince Oct 12 '12 at 05:35
  • Hi, I have in my code: `return new JsonModel($results)`. Where do I have to put that 3 lines of code to change headers? I tried putting them before the return, but it doesn't work. – Oscar Fanelli Mar 31 '14 at 16:34
  • Bear in mind that your useful priorities are lower than -10000 for the `render` event and higher than -10000 for the `finish` event. Those are respectively `Zend\Mvc\View\Http\DefaultRenderingStrategy` and `Zend\Mvc\SendResponseListener` priorities. – Stefano Torresi Apr 03 '14 at 11:06