如何在ajax的授权和cors的第二个响应中显示内容?

Posted

技术标签:

【中文标题】如何在ajax的授权和cors的第二个响应中显示内容?【英文标题】:How to show the content in second response for ajax's authorization and cors? 【发布时间】:2019-02-19 22:04:51 【问题描述】:

我已经在 vps 中建立了基本的授权和 cors。

curl -X 选项 -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"';
?>

您可以看到授权和cors处于良好状态。

我本地目录/var/www/html中的test-ajax-cors.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>

http://111.111.111.111中的remote.php。

cat /var/www/html/remote.php

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

输入127.0.0.1/test-ajax-cors.html,点击show content, 1.我收到警报信息:错误 2.remote.php被127.0.0.1/test-ajax-cors.html调用了两次(127.0.0.1/test-ajax-cors.html中的show content按钮被点击了一次)。

什么时候第一次调用remote.php,remote.php的resposne中没有内容。 第一个请求可能是 CORS 预检请求,浏览器发送一个没有任何 Authorization 标头的 OPTIONS 请求,在我的情况下,服务器向浏览器发送一个 200 状态码,这意味着一切都处于良好状态。

第二次调用remote.php时remote.php的响应内容。 如何使第二个响应中的内容由127.0.0.1/test-ajax-cors.html显示。 感谢 Sally CJ 的通知。

yum install mod_php
systemctl restart httpd

输入127.0.0.1/test-ajax-cors.html,点击show content。 1.alert错误信息

2.remote.php被调用了两次,所有remote.php的响应都是一样的。

"name","myname"

内容如我所愿,为什么无法在网页127.0.0.1\test-ajax-cors.html显示,导致提示错误信息?

【问题讨论】:

似乎服务器没有“看到”/处理/提供文件 remote.php 作为 PHP 文件。尝试检查您的 Apache 配置和/或 .htaccess 文件。 yum install mod_php systemctl 重启 httpd alert("error"); 更改为 alert(e.responseText); 看看它的内容。 @it_is_a_literature 你期待一个 JSON 编码的响应(你在jQuery.ajax() 调用中将dataType 设置为json),如果你在控制台中输入JSON.parse('"name", "myname"'),你会出错;因此,这可能是您收到“错误”警报的原因。因此,请确保输出有效的 JSON 字符串 - 在 PHP 中,您可以使用 json_encode() 【参考方案1】:

首先,您的服务器似乎没有正确设置,因为您的 PHP 脚本没有执行,并且响应只是返回脚本的内容(我看到您已经用 mod_php 解决了这个问题) .

其次,"name", "myname" 不是有效的JSON。您的回复应该是 "name": "myname" 或者为方便起见,您应该始终使用 json_encode PHP 数组,例如:

<?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);

这样您的JSON将始终有效,或者至少您会看到有助于调试的错误。

更正您的回复后,您可以执行以下操作:

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

请注意,JQuery 足够聪明,可以判断请求是否为 pre-flight 请求,因此您的回调应仅在第二个请求交付内容时触发。

【讨论】:

【参考方案2】:

@it_is_a_literature 关于第一个问题(来自错误部分的警报),您应该在您的 php 文件中设置标题(header('Content-Type: application/json');) 并使用 json_encode 和 echo。对于两次函数调用,您应该在函数 ajax() 的末尾return false

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>

响应.php

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

回复:

【讨论】:

我的回复中已经提到了“标题”和json_encode。另外,你的回答完全没有意义。何return false 帮忙?该函数没有被调用两次,需要两个请求,并且由 JQuery 自动发出,因为它是一个 CORS 请求。

以上是关于如何在ajax的授权和cors的第二个响应中显示内容?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 sencha 中 json 响应的第一个组合值填充第二个组合

如何在Ajax的第二个请求中修复数据库中插入的0值?

如何根据使用 jQuery/AJAX 和 PHP/MySQL 选择的第一个下拉列表填充第二个下拉列表?

CORS - 带有“授权”的 Ajax 或 XMLHttpRequest 类型 GET 获取错误 307

如何使用情节提要为 ipad 的 xcode 中的第一个视图内的第二个视图添加动画

如何连续响应两列?在第一个文本中,在bootstrap 4中的第二个图像中