【问题标题】:Ajax request not printing html responseAjax 请求不打印 html 响应
【发布时间】:2017-07-11 00:01:19
【问题描述】:

我有一个ajax 请求,它获取一些数据并返回我在页面上打印出来的html 响应。问题是由于某种原因html 响应没有被打印,只有文本数据。当我在浏览器控制台中检查时,正在返回正确的响应。

这里是ajax 函数:

function getRating(work_id, selectorToWriteTo)
{
     $.ajax({
        url: '/read/getRatingsForGivenWork',
        type: 'GET',
        dataType: 'html',
        async: true,
        data: { field1: work_id},
        success: function (data) {
            //your success code
            $(selectorToWriteTo).html(data);
        },
        error: function (xhr, ajaxOptions, thrownError) {
            alert("Error: " + thrownError);
        }
     });
}

返回html数据的函数:

public function getRatingsForGivenWork()
{
     $ratings = $this->getModel ( 'read', 'getRatingsForGivenWork', $_GET['field1']);
     if($ratings !== null)
     {      
          print "<div class=\"ui small star rating\" data-rating=\"" . $ratings ."\" data-max-rating=\"5\">Leave rating</div>";
     }
     else
     {
          print 0;
     }

   }

我在哪里调用 ajax 函数:

<div class="extra">
     <script>
          document.write(getRating(<?php echo $row['works.work_id']; ?>, '.extra'));
     </script>    
</div>

Chrome 开发者工具中的响应:

Chrome 控制台:

返回正确的响应,但它不会在页面上打印 html。有谁知道这是为什么?

【问题讨论】:

  • 实际上,我认为它不能解决您的问题,但您正在覆盖您的 JavaScript 代码,因为它位于 div 中。您能告诉我们 Chrome 控制台中的内容吗?
  • 我已经用 Chrome 控制台响应的屏幕截图编辑了我的问题
  • 这不是您显示的控制台...您显示的是网络 > 响应的屏幕截图。我需要控制台屏幕。
  • @Seblor 啊,我的错!我现在已经包含了控制台屏幕截图。
  • 尝试从div 中删除&lt;script&gt;...&lt;/script&gt;

标签: jquery html ajax


【解决方案1】:

您是否查看过您的 AJAX 请求是否返回了任何数据? 尝试打开 Inspect Element 窗口并转到 Network。

尝试发送您的请求,看看有什么响应。

另外,你要向getRating(work_id, selectorToWriteTo)函数发送什么?

selectorWriteTo 包含什么?

【讨论】:

  • 它返回正确的数据,如上面屏幕截图所示,从 Chrome 的开发人员工具中看到的响应选项卡中,getRating() 的调用方式如下:document.write(getRating(&lt;?php echo $row['works.work_id']; ?&gt;, '.extra')); 其中.extra 是为其输出 html 数据的元素的类
  • 您能否确认您是否有多个'.extra' 元素?它们是默认隐藏的吗?你能试着先说alert(data)吗?
  • 我可以确认没有多个 .extra 元素,当我提醒数据时,它的提醒与响应完全相同。只是不在页面上打印。
  • 你能创建一个&lt;div id="test"&gt;&lt;/div&gt; 并使用“#test”而不是“.extra”吗?我也想知道你为什么在 document.write 中调用这个方法,因为它不会产生任何好处。
  • 刚刚创建了一个&lt;div id="test"&gt;&lt;/div&gt;并使用了#test,做的完全一样
【解决方案2】:

你为什么不尝试使用。 Load 用于加载 html 内容并将其显示为页面的一部分。或许这会对你有所帮助。

 $(selectorToWriteTo).load(data);

【讨论】:

  • 这也打印 undefined,为什么当返回的响应是完美的 html 时打印 undefined?
  • 请问您是如何通过选择器的?它只是类或 ID 名称,还是您将整个选择器作为 .selector 或 #selector 传递???
  • 我这样传递类名:document.write(getRating(&lt;?php echo $row['works.work_id']; ?&gt;, '.extra')); .extra 位是选择器,注意分隔参数的逗号,
  • 我怀疑您传递的 .extra 选择器需要包含在引号中,并检查选择器是否存在于 DOM 上,我知道您说它可用,但只需确认一下使用 if($('some_element').length == 0) { alert("Not Present"); }
  • 是的,刚刚用 if($('.extra').length == 0) { alert("Not Present"); } else { alert("present"); 测试过它并显示警报
【解决方案3】:

您可以尝试将 id 设置为 HTML div,然后将其作为选择器传递;并将函数调用保持在 div 之外。

<div class="extra" id="div1">
</div>

<script>
    getRating(<?php echo $row['works.work_id']; ?>, '#div1');
</script> 

【讨论】:

  • 这不会改变结果,输出仍然没有被打印出来
  • success Ajax 请求事件中将data 分配给一个局部变量,然后使用简单的javascript 将该变量分配给div 的innerHTML 属性。还要确保 div 没有包含在任何其他 html 标记之间,例如 PRE
【解决方案4】:

我相信您在这里遇到了竞态条件问题,为了解决该问题,我将建议进行一些更改,首先,我看到您正在循环可能来自 SQL 调用的响应?所以,您是每次迭代触发一次你的js代码,你总是替换你的.extra div的html,这意味着你正在从那里删除脚本标签(不应该是一个真正的问题,因为php代码在JS之前执行)但是我建议如下:

首先,移动脚本:

<div class="extra"></div>
<script>
    document.write(getRating(<?php echo $row['works.work_id']; ?>, '.extra'));
</script>

我建议你将&lt;div class="extra"&gt;&lt;/div&gt; 移到 PHP 循环之外(如果它在里面,否则没问题),这样你只会得到一个 div。并将脚本标签留在循环内。 现在,每次您的 ajax 请求成功时,您都将替换整个 .extra html,因此循环的最后一次出现可能会在您的 else 语句中结束,因此 print 0;。我还建议您打印其他内容而不是 0,例如 &lt;span&gt;You cannot rate this&lt;/span&gt;,这样您就会注意到发生了什么。 现在,为了不替换整个 divs html,请改用 append:

$(selectorToWriteTo).append(data);

要检查的另一件事是 ui small star rating extra 类的 CSS 并验证它们是否正在显示,而不是 display: none;visibility: hidden;

【讨论】:

  • 我明白你想说什么,但这实际上与竞争条件和首先渲染的内容无关,实际上比这要简单得多。元素在循环中打印出来就好了,如果在我的服务器端代码中我打印一个简单的&lt;p&gt;Rate me&lt;/p&gt; 那么它会在页面上准确地打印出来。但是,当我打印元素 &lt;div class="ui small star rating" data-rating="0" data-max-rating="5"&gt;Leave rating&lt;/div&gt; 时,我尝试打印的特定 div 标签似乎有问题,而不是打印的顺序。
  • 然后检查我的答案的最后一部分,并检查您的 CSS 是否有 div 具有的类(ui 小星级),以查看它们是否被隐藏或不可见。
  • 检查了 CSS 没有 display:none 或类似的东西,但我已经意识到别的事情,你指出 PHP 代码在 js 之前执行,在我的代码中,就在我拥有的 ajax 函数上方这段代码:$(document) .ready(function(){ $('.ui.small.rating').rating('disable'); }); 初始化星级功能。 PHP 在 js 之前渲染的事实是否存在问题?
【解决方案5】:

在深入研究之后,我设法找出了问题所在。这一切都归结为 PHP 是在 JavaScript 之前加载的。

在我的 PHP 循环中,我打印出数据库表中的每个项目。对于每个项目,我都调用了 ajax 函数 getRating(work_id, selectorToWriteTo) 以便它打印出评分。

ajax函数的结果是输出如下元素:

<div class="ui small star rating" data-rating="3" data-max-rating="5">Leave rating</div>

此元素需要 javascript 初始化才能正常工作和显示。我将初始化包装在 document.ready() 中,如下所示:

$( document ).ready(function() {
   $('.ui.small.rating').rating();
});

这意味着星级评分显然只有在文档准备好并完全加载后才被初始化,在我的例子中是在 PHP 代码执行之后,所以 PHP 在初始化之前输出元素,这就是为什么什么都没有正在显示。

解决此问题的一种方法是使用 JavaScripts window.onload 事件,以便在页面完全加载时初始化评分:

window.onload = function(event){
    event.stopPropagation(true);
    $('.ui.small.rating').rating();
}

现在输出元素,但不太清楚为什么,因为我必须更深入地查看onload 事件。 仍然有一些不寻常的行为,在大多数项目上,元素打印得很好,但是当我再次重新加载页面几次时,一些项目中缺少它,完全随机的行为。

感谢大家的帮助。

更新:

我最近发现了一个更强大、更快的解决方案。我只需要将初始化封装在 setTimeOut 函数中:

window.onload = function(event){
    setTimeout(function(){
       event.stopPropagation(true);
       $('.ui.small.rating').rating('disable');
    }, 0);

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 2018-10-14
    • 2017-07-03
    • 2015-01-26
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多