【问题标题】:What's the most efficient way to make a log entry on a server from javascript?从 javascript 在服务器上创建日志条目的最有效方法是什么?
【发布时间】:2011-11-30 07:37:03
【问题描述】:

假设我有一个脚本需要在服务器上记录一些内容。我有一个像http://myServer.com/recordLog 这样的端点,我可以用一些参数来实现它,它会记录下来。一些警告:

  • 我可以控制服务器返回的内容
  • 这将每天发生数百万次。
  • 效率至关重要。
  • 脚本可能是从另一台服务器和 iframe 中加载的,因此存在浏览器安全问题。
  • 我根本不关心响应。就算出现通讯故障,我也不会做任何事情。
  • 我不能做任何影响页面其余部分状态的事情。

我的第一个想法是进行 ajax 调用——这似乎是一种“现代”、“正确”的方式。但是,在某些情况下,这可能会引发跨域安全问题。

我的另一个想法是将 1x1 像素图像或空的<script> 加载到内存中。比如:

var i = new Image;
i.src = "http://myserver.com/recordLog?foo=bar&baz=buz"; // returns 1x1 gif

或:

// this is similar to ajax-p, I suppose
var s = document.createElement('script');
s.type= 'text/javascript';
s.src= "http://myserver.com/recordLog?foo=bar&baz=buz"; // returns empty text file

我很确定没有必要将图像或脚本放入 DOM。仅仅设置 src 就会导致浏览器发出请求。

这两个非常相似。一般标准似乎是使用像素,但我认为这是一个保留。我认为空脚本会稍微小一些。两者有什么优势?

还有其他想法/方法吗?任何我没有想到的隐藏问题(例如,可能无法按预期工作的古老浏览器)?

【问题讨论】:

  • 您需要对记录器进行身份验证吗?即,您是否关心攻击者是否可以用伪造的日志消息填充您的日志?
  • 什么跨域安全问题?你能详细说明一下吗?

标签: javascript ajax logging


【解决方案1】:

如果您想提交查询,为什么不创建一个表单并提交它。

<iframe id=invisibleiframe ...>
<form target=invisibleiframe action=log>
  <input type=hidden name=logmessage value=log>
</form>
<script>forms.log.submit()</script>

【讨论】:

  • 他提到了 XHR,这就是make an ajax call 的意思。他提到它不能跨域工作。
  • 嗯...使用不可见的 iframe 可能会起作用,但它似乎比我建议的方法开销更大——我必须创建更多元素,并且可能实际上将它们注入DOM。
  • @slebetman 它确实可以跨域工作。如果域不匹配,您将无法读取 HTTP 响应,但您可以发送 HTTP 请求。
  • 也许有办法解决它,但 Chrome 会抛出一个错误。 XMLHttpRequest 无法加载 [远程 url]。 Access-Control-Allow-Origin 不允许 Origin [脚本服务器]。
  • @sprugman,XHR 不能跨域工作。为此,您需要 CORS。我编辑删除了对 XHR 的所有引用。
【解决方案2】:

我没有看到这个问题:

var xhr = new XMLHttpRequest;
xhr.open( 'GET', 'http://myserver.com/recordLog?foo=bar&baz=buz' );
xhr.send();

【讨论】:

  • 也许有办法绕过它,但如果我从 someOtherServer.com 运行它,Chrome 会抛出错误。 XMLHttpRequest 无法加载 [远程 url]。 Access-Control-Allow-Origin 不允许 Origin [脚本服务器]。
  • @sprugman Chrome 和其他浏览器会抛出错误,因为您的页面不允许访问 HTTP 响应。但那是无关 - 你不需要你在问题中所说的服务器响应。重要的是无论如何都会发出 HTTP 请求 ,因此您的服务器会收到请求。
【解决方案3】:

只需创建一个iframe 并指向一些不返回任何内容的日志记录 URL。

【讨论】:

  • 空 iframe 与空脚本的想法非常相似,但在某种程度上可能更安全一些。谢谢。
【解决方案4】:

或者您可以使用NoSQL 数据库来存储日志消息,例如CouchDBMongoDB。例如,CouchDB 存储 JSON 文档,您使用 RESTful API 与服务器交互。另一方面,MongoDB 以 BSON 格式(一种受 JSON 启发的二进制格式)存储文档。有很多示例可以让您访问他们的网站。

【讨论】:

  • 除非我误解了你,那是关于如何在服务器端创建/存储日志条目,但与如何将日志条目从浏览器传递到服务器无关。
  • 前面说过,可以通过RESTful接口与服务器交互,也就是可以通过AJAX直接向数据库服务器发送日志消息,采用JSON格式。这些 DBMS 针对此类场景进行了高度优化。
  • 您可以查看这篇文章以获得概述:CouchDB for access log aggregation and analysis
  • 但我仍然有使用 AJAX 的跨域问题。服务器对请求的处理与讨论无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-01
  • 2015-04-10
  • 2010-09-23
  • 1970-01-01
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多