CORS using ajax within PhoneGap+jQuery Mobile not

2019-02-15 18:04发布

问题:

So I'm building an application using Phone Gap and jQuery mobile.

When using ajax to get a json response from a whitelisted server I am getting an error response. Nothing is showing in console however. The weird thing is that when testing the app within a web browser it works fine, it's only when I launch to my iphone device that it throws a strop.

It is worth saying now that the site I'm hosting my php scripts on is white listed within Phone Gap. I am using * in the array (just in case this makes a difference). I have worked out a jsonp workaround for this but don't want to use it - I feel if it's working in browsers it must be possible on the device. I'm hoping it's a simple fix...

Here is my simple php script just echoing a json string.

<?php
header('Access-Control-Allow-Origin: *');
$arr = array('a' => 1, 'b' => 2);
echo json_encode($arr);
?>

Here is the JS

    $('#registerUser').submit(function() {
          $.ajax({
                 url: 'http://www.mydomain.co.uk/path/register/add_user.php',
                 type: 'post',
                 dataType: 'json',
                 crossDomain : true,
                 timeout: 5000,
                 success: function(msg){
                    alert(msg.a);
                 },
                 error: function(){
                    alert('There was an error loading the data.');
                 }
                 });
          });
    });

edit: I also have this js on the page...it's recommended on the jquery mobile docs to use this when using Phone Gap

        <script>
        $( document ).on( "mobileinit", function() {

            $.mobile.allowCrossDomainPages = true;
            $.support.cors = true;
        });

        </script>

And the form - I don't think this is necessary...

           <form id='registerUser' action="" method="POST">
                <div data-role="fieldcontain">
                    <label for="name">Name:</label>
                    <input type="text" name="name" id="name" value=""  />
                    <label for="name">Email:</label>
                    <input type="text" name="email" id="email" value=""  />
                    <label for="name">Password:</label>
                    <input type="password" name="password1" id="password1" value=""  />
                    <label for="name">Re-enter password:</label>
                    <input type="password" name="password2" id="password2" value=""  />
                    <br>
                    <button type="submit" aria-disabled="false">Submit</button>
                </div>
            </form>

Thanks for the help in advance!

回答1:

The simplest thing to try is augmenting your PHP server with the following:

<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET,PUT,POST,DELETE');
header('Access-Control-Allow-Headers: Content-Type');
$arr = array('a' => 1, 'b' => 2);
echo json_encode($arr);
?>

You will also need to make sure that your PHP server allows OPTIONS HTTP requests.

The longer answer is that the dataType: 'json' in your JS code is triggering a CORS preflight request. A preflight request basically asks the server for permission to make the actual request. You can learn more about CORS preflight here: http://www.html5rocks.com/en/tutorials/cors/



回答2:

I've encountered cases where Access-Control-Allow-Origin: * was actually ignored by the client. I believe the "proper" way (see the w3c spec to confirm this) to allow all domains via CORS is to actually grab the origin domain from the request header, then dynamically apply that origin to the Access-Control-Allow-Origin header of the response, rather than using the wildcard character, to ensure that the client will respect the header.



回答3:

Okay so it turns out there wasn't an issue with the code. It seemed that the app was cacheing the error result or something. I killed the app and relaunched it and all works fine now. From reading around it seems iOS6 safari caches POST which is different to previous versions.

I have added this in my ajax call to prevent caching the POST.

 headers: { "cache-control": "no-cache" }

I hope this helps someone else as it has been a pain!

Thanks for the replies



回答4:

My experience with this issue proved to be caused by the fact that I was using httpS with an "invalid" SSL certificate. iPhone mobile safari and webview did not trust the SSL certificate and so did not make the AJAX request.

I was able to complete development by temporarily using plain HTTP.

My CORS headers were:

Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With,Authorization