区分用户请求和 AJAX/Resource 请求

Differenciate Between User Requests and AJAX/Resource Requests

我正在尝试使用 Node.js(使用 http.createServer())创建一个应用程序,它将是一个单页应用程序,通过 XMLHttpRequest 请求数据。为此,我需要能够区分导航到我的域的用户和 AJAX 请求以及浏览器为 linked 资源生成的请求。

如果请求来自用户,我总是希望 return 将处理请求内容的 index.html 页面,但如果请求是浏览器生成的或 AJAX 并且用于 CSS、Javascript 或其他 linked 文件我想为这些文件提供服务。有什么方法可以检测到这个吗?

查看针对不同文件类型的请求 header,我看到 referer header 在页面生成内容请求时出现。我想这就是我正在寻找的解决方案,但是当用户单击页面上的 link 时也会设置 header 使其无用。

唯一似乎发生变化的是 accept header,它可以工作但可能不是万能的解决方案。任何用户请求似乎总是将 text/html 作为首选 return 类型,而不管输入的是哪个 url。我可以检测到这一点,但我很确定 AJAX 对 html 文件的请求也会有 accept header 这会导致问题。

这里有什么我遗漏的吗(我可以寻找的任何 header 或属性)?


编辑: 我不需要保护文件的解决方案,我不关心用户通过自己的请求绕过它。我的意图不是隐藏文件或使它们安全,而是将请求的任何数据保留在应用程序的范围内。

例如,如果用户导航到 http://example.com/images/someimage.jpg,他们将看到 index.html 文件,该文件可以在更丰富的上下文中显示图像并包含所有 link以及与之配套的功能。

TL/DR: 我需要检测何时有人试图访问该应用程序,然后为他们提供索引页面并向他们发送他们想要的内容。我还需要检测浏览器何时请求应用程序所需的资源(JS、CSS、HTML、图像等),以便能够实际 return 资源而不是索引文件.

就 HTTP 协议而言,user-generated-querybrowser-generated-query 之间没有区别。

每个查询都只是...一个查询。 您可以使用命令行进行查询,使用浏览器,您可以单击 link,通过 telnet 发送一些 ascii 文本,请求代理为您进行查询,服务器的目标永远不会识别如何查询是由用户请求的。

例如,请参阅用户在反向代理缓存上发出的请求,此查询永远不会到达您的服务器(响应来自缓存),构建此响应的第一个查询可能是由 真实用户或通过浏览器。

就安全性而言,试图控制用户从不请求数据 by-himself 无法通过检测查询是真正的人工点击(和搜索google 用于点击劫持,如果你想害怕的话)。浏览器可以发出的每一个查询也可以被用户播放,每一个,你都无法阻止。

有些浏览器插件甚至可以 pre-fetching,检测页面上的 link 并在您自己执行之前发出请求(如果是 GET 查询)。

对于ajax,一些库如JQuery会添加一个X-Requested-With: XMLHttpRequest头,这在大多数框架上用于检测ajax模式。 但是依赖位置策略会更稳健(比如使用 /format/ajax 进行 ajax 查询,这也可以用于其他方式(如 /format/json/format/html, 或 /format/csv).

花时间在基于位置策略的路由上肯定更有用。

但有一件事会有所不同,POST 查询不是幂等的,这意味着浏览器无法在 没有 真实用户的情况下进行 POST 查询交互,因为 POST 查询可能会改变会话的状态或服务器数据的状态(但是 js 可以进行 POST 查询,这只是浏览器的默认行为)。浏览器永远不会自动检索 POST 查询,因此您可以创建一个网站,其中所有用户交互都是 POST 查询(通过表单或通过一些 js 更改 link 点击发送 POST ajax 查询)。但我不是那是你真正的目标。

从技术上讲,这不是问题的答案,但我找到了一个简单的解决方案,可以满足我的要求:在所有基于应用程序的请求前加上一个子域,例如。 http://data.example.com/。然后检查该子域的 host header 非常简单:如果存在则发送资源,否则发送索引页。