80

自 2012 年 6 月 12 日 11:20 TU 以来,我在 varnish/apache 日志中看到了非常奇怪的错误。

有时,当用户请求一个页面时,几秒钟后我会看到一个类似的请求,但 url 中最后一个 / 之后的所有字符串已被“undefined”替换。

示例: http ://example.com/foo/bar触发http://example.com/foo/undefined请求。

当然这些“未定义”页面不存在,而是返回了我的 404 页面(这是具有标准布局的自定义页面,而不是经典的 apache 404)

  • 任何页面都会发生这种情况(从主页到最深处)
  • 使用各种浏览器(主要是 Chrome 19,还有 firefox 3.5 到 12、IE 8/9...),但只有 1% 的流量。
  • 这些请求发送的标头是经典标头(并且没有 ajax 标头)。
  • 对于给定的 ip,这似乎是随机发生的:有时在访问的第一页上,有时在访问期间的随机页面上,有时在访问期间的几个页面上......

当然,这看起来像是一个 javascript 问题(我使用的是 google 托管的 jquery 1.7.2),但几天以来我的 js/html 或服务器配置完全没有任何变化,而且我之前从未见过这种错误. 当然,在 html 中没有这样的链接。

我还注意到一些有趣的事实:

  • 未定义的请求永远不会被找到作为其他页面的引用者,而是将“真实”页面用作相同 IP 的以下请求的引用者(用户可以使用 404 页面上的经典菜单)
  • 我在 Google Analytics 中没有看到这些页面的任何痕迹,所以我假设没有执行任何 javascript(跟踪器存在于所有页面上,包括 404)
  • 没有人就此联系过我们,即使我在网站的社交网络中提到了这个问题
  • 大多数用户在那之后继续访问

所有这些事实让我认为问题是在浏览器中悄悄发生的,可能是由昨天更新的浏览器中集成的错误插件、防病毒、浏览器栏或糟糕的制造商软件触发的(但我没有发现任何已发布的插件昨天为 chrome、firefox 和 IE)。

这里有没有人注意到同样的问题,或者有更完整的解释?

4

8 回答 8

21

没有简单直接的答案。

您将不得不对此进行调试,并且由于 URL 中的“未定义”字样,它可能是 JavaScript。然而,它不一定是 AJAX,它可以是 JavaScript 创建由浏览器自动解析的任何 URL(例如,在图像标签上设置 src 属性、设置 css-image 属性等的 JavaScript)。我大部分时间都使用安装了Firebug的Firefox,所以我的方向将牢记这一点。

Firebug 初始设置

如果您已经知道如何使用 Firebug,请跳过此步骤。

在安装并重新启动 Firefox for Firebug 之后,您将不得不启用大部分 Firebug 的“面板”。要打开 Firebug,您的浏览器右上角会出现一个看起来像火虫/昆虫的小东西,或者您可以按 F12。单击 Firebug 选项卡“控制台”、“脚本”、“网络”并通过打开它们并阅读面板信息来启用它们。您可能需要刷新页面才能使它们正常工作。

调试用户交互

导航到打开 Firebug 且“网络”面板处于活动状态时出现问题的页面之一。在 Net 面板中会有几个选项:“Clear”、“Persist”、“All”、“Html”等。确保选择 ALL。不要在页面上做任何事情,尽量不要将鼠标悬停在上面的任何内容上。浏览请求。对无效 URL 的请求将显示为红色,并且状态可能为 404 Not Found(或类似)。

加载时看到了吗?跳到下一部分。

在初始加载时看不到它?开始使用您的页面并在此处继续。

开始单击每个功能,将鼠标悬停在所有内容上,等等。注意网络面板并注意失败的请求。您可能必须要有创意,但要继续使用您的应用程序,直到您看到浏览器发出无效请求。如果页面发出许多请求,请随意点击网络面板左上角的“清除”按钮将其清除一下。

如果您提交页面并看到失败的请求很快就消失了,但由于下一页加载而丢失了它,请通过单击“网络”面板左上角的“持久”来启用持久性。

一旦它发生了,它应该考虑你做了什么来实现它。看看你能不能让它再次发生。在弄清楚是什么用户交互导致它发生后,深入研究该代码并开始寻找发出无效请求的事物。

您可以使用“脚本”选项卡在 JavaScript 中设置断点并单步执行它们。调查通过 $(element).bind/click/focus/etc 或从老派事件属性(如 onclick=""/onfocus="" 等)完成的事件处理程序。

如果请求在页面加载后立即发生

这将是一个有点难以钉住。您需要转到“脚本”选项卡并开始为每个在加载时运行的脚本添加断点。您可以通过单击 JavaScript 行的左侧来执行此操作。

重新加载你的页面,你的断点应该会阻止浏览器加载页面。按脚本面板上的“继续”按钮。转到您的网络面板,看看您的请求是否已提出,继续直到找到。您可以使用它来缩小发出请求的范围,方法是慢慢添加越来越多的断点,然后步入和退出函数。

你在你的代码中寻找什么

类似于以下内容:

var url = workingUrl + someObject['someProperty'];

var url = workingUrl + someObject.someProperty;

请记住, someObject 可能是 object {}、 array[]或任何内部浏览器类型。关键是将访问一个不存在的属性。

我没有看到任何 404/红色请求

然后,无论是什么原因,您的测试都不会触发它。尝试使用更多的东西。关键是您应该能够以某种方式使请求发生。你只是还不知道。它必须显示在网络面板中。唯一不会发生的情况是当你没有做任何触发它的事情时。

结论

没有超级简单的方法可以确定到底发生了什么。但是,使用我概述的方法,您至少应该能够接近。这可能是你甚至没有考虑过的事情。

于 2012-06-20T21:32:56.390 回答
17

根据这篇文章,我对“Complitly”Chrome 插件/恶意软件进行了逆向工程,发现此扩展程序正在注入“改进的自动完成”功能,该功能在每个输入文本字段为 NAME 或“搜索”、“q”和许多其他的 ID。

我还发现 enable.js 文件(complitly 文件之一)正在检查一个名为“suggestmeyes_loaded”的全局变量,以查看它是否已经加载(如 Singleton)。因此,将此变量设置为 false 会禁用插件。

要禁用恶意软件并停止“未定义”请求,请将其应用于您网站上具有搜索字段的每个页面:

<script type="text/javascript">
    window.suggestmeyes_loaded = true;
</script>

此恶意软件还会将您的用户重定向到“searchcompletion.com”网站,有时会显示竞争对手的 ADS。所以,应该认真对待。

于 2013-01-05T17:34:00.977 回答
8

您已正确确定这与undefinedJavaScript 问题有关,并且如果您的站点用户没有抱怨看到错误页面,您可以检查以下内容。

如果 JavaScript 用于设置或更改图像位置,则有时会发生 anundefined进入 URI 的情况。

发生这种情况时,浏览器会很高兴地尝试加载图像(没有 AJAX 标头),但它会留下提示:它设置了一个特定的Accept:标头;而不是text/html, text/xml, ...它将使用image/jpeg, image/png, ....

确认此类标题后,您已将问题范围缩小到仅图像。找到根本原因可能需要一些时间:)

更新

$.fn.attr()为了帮助调试,您可以在将某些内容分配给未定义时覆盖并调用调试器。像这样的东西:

​(function($, undefined) {
    var $attr = $.fn.attr;

    $.fn.attr = function(attributeName, value) {
        var v = attributeName === 'src' ? value : attributeName.src;

        if (v === 'undefined') {
            alert("Setting src to undefined");
        }

        return $attr(attributeName, value);
    }
}(jQuery));
于 2012-06-20T09:23:34.753 回答
3

已经确定的一些事实,尤其是在这个线程中:http ://productforums.google.com/forum/#!msg/chrome/G1snYHaHSOc/p8RLCohxz2kJ

它发生在根本没有 javascript 的页面上。这证明它不是页面编程错误

用户没有意识到这个问题并继续愉快地浏览。

它发生在该人访问该页面几秒钟后。

它不会发生在每个人身上。

发生在多个浏览器(Chrome、IE、Firefox、Mobile Safari、Opera)上

发生在多个操作系统(Linux、Android、NT)上

发生在多个 Web 服务器(IIS、Nginx、Apache)上

我有一个 googlebot 跟踪链接并声称相同的引荐来源的案例。他们可能只是想变得聪明,浏览器将其传达给母舰,然后母舰设置机器人进行调查。

我相当确信它是由插件引起的。Complitly 是其中之一,但它不支持 Opera。还有很多其他的。

尽管移动浏览器不利于插件理论。

系统管理员报告说,通过在页面上添加一些 javascript 来欺骗 Complitly 认为它已经初始化,从而导致严重下降。

这是我对 nginx 的解决方案:

location ~ undefined/?$  {
  return 204;
}

这将返回“是的,但没有内容适合您”。

如果您在 website.com/some/page 上并且(以某种方式)导航到 website.com/some/page/undefined 浏览器将显示 URL 已更改,但甚至不会重新加载页面。前一页将保持在窗口中的状态。

如果由于某种原因这是用户所经历的事情,那么他们将获得干净的 noop 体验,并且不会打扰他们正在做的任何事情。

于 2013-10-20T13:12:47.343 回答
2

这听起来像是一种竞争条件,其中变量在使用之前没有正确初始化。根据您的评论,考虑到这不是 AJAX 问题,下面列出了几种解决方法。

连接 Javascript 异常记录器:这将帮助您在日志中捕获几乎所有随机 javascript 异常。大多数时候,程序错误会在这里冒泡。把它放在任何脚本之前。您需要在服务器上捕获这些并将它们打印到您的日志中以便稍后进行分析。这是你的第一道防线。这是一个例子:

window.onerror = function(m,f,l) {
    var e = window.encodeURIComponent;
    new Image().src = "/jslog?msg=" + e(m) + "&filename=" + e(f) + "&line=" + e(l) + "&url=" + e(window.location.href);
};

搜索 window.location:对于这些实例中的每一个,您应该将日志记录或检查未定义的 concats/appenders 到您的 window.location。例如:

function myCode(loc) {
    // window.location.href = loc; // old 
    typeof loc === 'undefined' && window.onerror(...); //new
    window.location.href = loc; //new
}

或稍微清洁:

window.setLocation = function(url) { 
   /undefined/.test(url) ? 
         window.onerror(...) : window.location.href = url;       
}

function myCode(loc) {
    //window.location.href = loc; //old
    window.setLocation(loc); //new
} 

如果您有兴趣在此阶段获取堆栈跟踪,请查看:https ://github.com/eriwen/javascript-stacktrace

抓取所有未处理的未定义链接:除了 window.location 唯一剩下的就是 DOM 链接本身。第三步是检查所有未处理的 DOM 链接是否存在无效的 URL 模式(您可以在 jQuery 完成加载后立即附加此链接,越早越好):

$("body").on("click", "a[href$='undefined']", function() {
    window.onerror('Bad link: ' + $(this).html()); //alert home base
});

希望这会有所帮助。调试愉快。

于 2012-06-23T09:20:59.773 回答
1

我想知道这是否可能是一个广告拦截器问题。当我按 IP 地址搜索日志时,似乎特定用户对 /folder/page.html 的每个请求都后跟对 /folder/undefined 的请求

于 2012-09-14T16:16:46.510 回答
0

我不知道这是否有帮助,但我的网站在将一个特定的 *.webp 图像文件加载到多个浏览器中后将其替换为 undefined。您的网站是否托管 webp 图片?

于 2015-06-06T06:53:37.663 回答
0

我有一个类似的问题(但/null在控制台中有 404 错误)@andrew-martinez 的回答帮助我解决了。

原来我使用的是img带有空src字段的标签:

<img src="" alt="My image" data-src="/images/my-image.jpg">

我的想法是通过使用javascript(延迟加载)从data-src属性设置src属性来防止浏览器在页面加载时加载图像以便稍后手动加载。但是当与 iDangerous Swiper 结合使用时,该方法会导致错误。

于 2015-11-05T13:59:42.650 回答