Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show the content in second response for ajax's authorization and cors?

I have build basic authorization and cors in vps.

curl -X OPTIONS -i http://111.111.111.111

HTTP/1.1 200 OK
Date: Sat, 15 Sep 2018 08:07:37 GMT
Server: Apache/2.4.6 (CentOS)
Access-Control-Allow-Origin: http://127.0.0.1
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With
Allow: OPTIONS,GET,HEAD,POST,TRACE
Content-Length: 0
Content-Type: httpd/unix-directory

curl -u xxxx:xxxx -i http://111.111.111.111/remote.php

HTTP/1.1 200 OK
Date: Sat, 15 Sep 2018 08:08:07 GMT
Server: Apache/2.4.6 (CentOS)
Access-Control-Allow-Origin: http://127.0.0.1
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With
Last-Modified: Sat, 15 Sep 2018 07:54:13 GMT
ETag: "24-575e43f02c324"
Accept-Ranges: bytes
Content-Length: 36


<?php
echo  '{"name","myname"}';
?>

You can see that authorization and cors are in good status.

The test-ajax-cors.html in my local directory /var/www/html.

<script src="http://127.0.0.1/jquery-3.3.1.js"></script>
<script>
function Ajax( ) {
    var url = 'http://111.111.111.111/remote.php';
    $.ajax(url, {
        type:"post",   
        crossDomain: "true",
        dataType:"json",
        beforeSend:function(xhr) {
            xhr.setRequestHeader('Authorization',"Basic " + btoa("xxxx:xxxx"))},
        success:function(response){
        data = JSON.stringify(response);
            alert(data);
            mytext = $("#remote");
            mytext.append(data);
        },
        error: function (e) {
            alert("error");
        } 
    });
};
</script>

<input type="button" value="show content" onclick="Ajax();">
<p id="remote">the content on remote webpage</p>

The remote.php in http://111.111.111.111.

cat /var/www/html/remote.php

<?php
echo  '{"name","myname"}';
?>

Type 127.0.0.1/test-ajax-cors.html ,click show content,
1.i got alert info: error
2.remote.php was called for two times by 127.0.0.1/test-ajax-cors.html (the show content button in 127.0.0.1/test-ajax-cors.html was clicked for just one time).

the first response when to call remote.php for the first time, no content in remote.php's resposne.
The first request maybe a CORS-preflight request , browsers send an OPTIONS request without any Authorization header,and in my case the server send a 200 status code to browser,it means that everything is in good status.

enter image description here

The content in remote.php's response when to call remote.php for the second time.
How to make the content in second response to show by 127.0.0.1/test-ajax-cors.html.
Thank to Sally CJ's notice.

yum install mod_php
systemctl restart httpd

Type 127.0.0.1/test-ajax-cors.html ,click show content.
1.alert error info

enter image description here

2.remote.php were called for two times,all the response for remote.php are same.

{"name","myname"}

enter image description here enter image description here

The content is what i expect,why can't show it in webpage 127.0.0.1\test-ajax-cors.html,which result the alert error info?

like image 806
showkey Avatar asked Sep 15 '18 08:09

showkey


2 Answers

@it_is_a_literature regarding for first issue (alert from error section), you shall set the header in your php file(header('Content-Type: application/json');) and use json_encode with echo. And for twice function call you shall return false at the end of function ajax().

Test.html

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function Ajax( ) {
    var url = 'http://localhost:855/remote.php';
    $.ajax(url, {
        type:"post",   
        crossDomain: "true",
        dataType:"json",
        beforeSend:function(xhr) {
            xhr.setRequestHeader('Authorization',"Basic " + btoa("xxxx:xxxx"))},
        success:function(response){
        data = JSON.stringify(response);
            alert(data);
            mytext = $("#remote");
            mytext.append(data);
        },
        error: function (e) {
            alert("error");
        }
    });
    return false;
};
</script>

<input type="button" value="show content" onclick="Ajax();">
<p id="remote">the content on remote webpage</p>

Response.php

<?php
header('Content-Type: application/json');
echo  json_encode(array("name","myname"));
?>

Response:

First hit to Resposne.php

no second function call

like image 125
Hari Prasad Sharma Avatar answered Nov 07 '22 05:11

Hari Prasad Sharma


First of all, it looks like your server is not setup correctly, since your PHP script is not executed and response simply returns the contents of the script (I see you've already sorted that out with mod_php).

Secondly, {"name", "myname"} is not a valid JSON. Your response should be {"name": "myname"} or for convenience you should always json_encode a PHP array like:

<?php
// Set the correct Content-Type
// this helps when viewing in browser console, and is generally needed
header('Content-Type: application/json');

// Create an array with needed response data
$result = [
    'name' => 'myname'
];

// Convert PHP array to a correct JSON string and echo it
echo json_encode($result);

That way your JSONwill always be valid or at least you will see errors that will help you debug.

After you've corrected your response, you can do something like:

success: function(response, textStatus, jqXHR) {
    // var stringData = JSON.stringify(response); you don't need this
    // since jqXHR object already contains the raw response text

    // It's recommended to prefix variable name with $
    // that way you will always know that it is a JQuery object
    var $mytext = $("#remote");
    $mytext.text(jqXHR.responseText);

    // console.log(response); is better than alert 
    // unless you really need to pause the script
    alert(response.name);
}

Please note that JQuery is smart enough to see if a request is a pre-flight request, so your callbacks should be only triggered when the second request delivers the content.

like image 23
Arthur Avatar answered Nov 07 '22 04:11

Arthur