1

I'm use Cordova 5.2.0 to create a simple mobile application for Android and I try send a POST request to the server with Apigility 1.3.1 along with an additional module called 'ZfrCors' (ZfrCors is a simple Zend Framework 2 module that helps you to deal with Cross-Origin Resource Sharing), but the server responded with a status of 500 (Internal Server Error). Probably the fault causes header post like "Origin: file://"

I browse logs with Wireshark and see:

POST /mobileapp/user HTTP/1.1
Host: api.XXX.com
Connection: keep-alive
Content-Length: 15
Accept: */*                 
Origin: file://
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
Content-Type: application/json
Accept-Encoding: gzip, deflate
Accept-Language: en-US;q=0.6,en;q=0.4
{"name":"test"}

Here's my JavaScript Code:

            var data = {
                  name: 'test'
            };

            $.ajax({
               method: 'POST',
               url: 'http://api.XXX.com/mobileapp/user',
               data: JSON.stringify(data),
               contentType: 'application/json',
               error: function(jqXHR, textStatus, errorThrown)
               {
                   console.log(jqXHR);
                   console.log(textStatus);
                   console.log(errorThrown);
                   alert('error');
               },
               success: function(data, textStatus, jqXHR)
               {
                   alert('success');
               }
            });

The Config.xml file (Cordova configurations) contains

<access origin="http://api.XXX.com/mobileapp/user" />

In addition, the HEAD of index.html file includes

<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">

On the server side ZF2 module 'ZfrCors' seems to be configured correctly, because when I create a POST request, for example, by the 'HttpRequester'-add-on for Firefox, without header "Origin: file://" everything works fine

zfr_cors.global.php

return array(
'zfr_cors' => array(
      'allowed_origins' => array('*'),
      'allowed_methods' => array('GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'),
      'allowed_headers' => array('*'),
     // 'max_age' => 120,
     // 'exposed_headers' => array(),
     //'allowed_credentials' => true,
));

It seems to me that the problem is Cordova, Webview sending incorrect Origin header?

rafalli
  • 146
  • 1
  • 7
  • could you please change this data: JSON.stringify(data) to this data: data, and try it... Also post me if it worked – Dennis Weidmann Aug 26 '15 at 19:41
  • @Neo It did not work, I try also add dataType: "json" also does not work – rafalli Aug 26 '15 at 19:48
  • Ok, in your php, please try this... $appInput = json_decode(file_get_contents("php://input"), true); $name = urldecode($appInput["name"]); to get the json sent as data, because in your wireshark output the data is there – Dennis Weidmann Aug 26 '15 at 19:53
  • @Neo I found a partial solution to the problem. The problem is the server-side, ZF2 module 'ZfrCors'. It should be change the header "Origin: file: //" -> "Origin: file: ///" It appears that Android 4.x devices sent in the request header line "Origin: file://", 'ZfrCors' module interprets it wrong. A small change in the source code ZF2 made it work, but this solution is not official and temporary. – rafalli Aug 26 '15 at 21:04
  • @rafalli in which file you made change can you tell me complete path , I am also facing the same problem, thank you in advance – Sohail Yasmin Oct 19 '15 at 06:28
  • @SohailYasmin I changed function called "lazyLoadHeader" in file vendor\zendframework\zend-http\src\Headers.php, but I do not recommend doing this because it can affect other functionalities – rafalli Oct 28 '15 at 11:37

1 Answers1

0

I also had this problem with a Phonegap app.

I found a fix here: https://github.com/zf-fr/zfr-cors/issues/18

You should add in onBootstrap this code (or similar):

    $eventManager        = $e->getApplication()->getEventManager();
    $headers = $e->getRequest()->getHeaders();
    if ($headers->has('Origin')) {
        //convert to array because get method throw an exception
        $headersArray = $headers->toArray();
        $origin = $headersArray['Origin'];
        if ($origin === 'file://') {
            unset($headersArray['Origin']);
            $headers->clearHeaders();
            $headers->addHeaders($headersArray);
            //this is a valid uri
            $headers->addHeaderLine('Origin', 'file://mobile');
        }
    }

Or if you want more strict code you can found on the link above.

The issues is closed on zfr-cors so I think there will not be an official solution from zfr-cors that will just work with origin like file:// how cordova/phonegap send.

Daniel Dudas
  • 2,972
  • 3
  • 27
  • 39