自 2012 年 6 月 12 日以来,“未定义”随机附加到我网站上 1% 的请求 URL 中

"undefined" randomly appended in 1% of requested urls on my website since 12 june 2012

本文关键字:未定义 网站 URL 请求 随机 2012      更新时间:2023-09-26

自 2012 年 6 月 12 日 11:20 TU 以来,我在清漆/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问题(我使用的是谷歌托管的jquery 1.7.2),但是几天来我在js/html或服务器配置中绝对没有任何变化,我以前从未见过这种错误。当然,html中没有这样的链接。

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

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

所有这些事实让我认为问题在浏览器中悄无声息地发生,可能是由错误的附加组件、防病毒软件、浏览器栏或蹩脚的制造商软集成在昨天更新的浏览器中触发的(但我没有找到昨天为 chrome、Firefox 和 IE 发布的任何附加组件)。

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

没有简单的直接答案。

你将不得不调试它,由于URL中的"未定义"词,它可能是JavaScript。但是,它不一定是 AJAX,它可以是 JavaScript 创建任何由浏览器自动解析的 URL(例如,在图像标签上设置 src 属性、设置 css-image 属性等的 JavaScript)。我大部分时间都在安装Firebug的情况下使用Firefox,所以我的指示会考虑到这一点。

Firebug 初始设置

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

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

调试用户交互

导航到存在 Firebug 打开且"网络"面板处于活动状态的问题的页面之一。在"网络"面板中,将有几个选项:"清除","持久","全部","Html"等。确保选择了"全部"。不要在页面上执行任何操作,并且尽量不要将鼠标悬停在其上的任何内容上。查看请求。对无效 URL 的请求将为红色,状态可能为 404 未找到(或类似)。

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

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

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

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

一旦它做到了,它应该考虑你做了什么来实现这一目标。看看你是否能让它再次发生。在弄清楚是什么用户交互使它发生之后,深入研究该代码并开始查找发出无效请求的内容。

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

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

这将有点难以确定。您需要转到"脚本"选项卡,并开始向加载时运行的每个脚本添加断点。您可以通过单击JavaScript行的左侧来执行此操作。

重新加载页面

,断点应会阻止浏览器加载页面。按脚本面板上的"继续"按钮。转到您的网络面板,查看是否已提出您的请求,继续直到找到它。您可以使用它来缩小发出请求的位置,方法是缓慢添加越来越多的断点,然后单步执行和退出函数。

您在代码中查找的内容

类似于

以下内容的内容:

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

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

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

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

结论

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

基于这篇文章,我对"Complitly"Chrome插件/恶意软件进行了逆向工程,发现此扩展程序正在注入"改进的自动完成"功能,该功能在每个具有"搜索","q"和许多其他输入文本字段的输入文本字段的站点上抛出"未定义"请求。

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

要禁用恶意软件并停止"未定义"请求,请将此内容应用于您网站上带有搜索字段的每个页面:

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

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

您已经正确确定该undefined与 JavaScript 问题有关,如果您的网站用户没有抱怨看到错误页面,您可以检查以下内容。

如果使用 JavaScript 设置或更改图像位置,有时会发生undefined进入 URI。

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

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

更新

为了帮助调试,您可以重写$.fn.attr()并在将某些内容分配给 undefined 时调用调试器。像这样:

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

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

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

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

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

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

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

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

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

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

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

尽管移动浏览器与插件理论背道而驰。

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

这是我对nginx的解决方案:

location ~ undefined/?$  {
  return 204;
}

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

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

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

这听起来像是一种竞争条件,其中变量在使用之前未正确初始化。根据您的评论,考虑到这不是 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:对于这些实例中的每一个,您应该将日志记录或检查未定义的 concat/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
});

希望这是有帮助的。调试愉快。

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

div class="answers" 的请求>我不知道

这是否有帮助,但我的网站在多个浏览器中加载后,正在用未定义替换一个特定的 *.webp 图像文件。您的网站是否托管 webp 图像?

我遇到了类似的问题(但控制台中/null 404 错误),@andrew-Martinez 的回答帮助我解决了这个问题。

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

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

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