我正在开发一个需要同时在客户端和服务器端工作的JS-app(在浏览器中的Javascript和Node.js中),并且我希望能够重用部分代码。用于双方。
我发现这window
是一个只能在浏览器和global
节点上访问的变量,因此我可以检测代码在哪个环境中执行(假设没有脚本声明该window
变量)
他们是两个问题。
我应该如何检测代码在哪个浏览器中运行。例如,此代码是否可以。(此代码是内联代码,这意味着它被一些全局代码包围,可在两种环境中重复使用)
if window?
totalPath= "../examples/#{path}"
else
totalPath= “../../examples/#{path}”
如何在两种环境中使用全局变量?现在,我正在执行以下操作,但这确实感觉不对。
if window?
window.DocUtils = {}
window.docX = []
window.docXData= []
else
global.DocUtils= {}
global.docX = []
global.docXData = []
注意:这个问题有两个部分,但是因为标题是“环境检测:node.js或浏览器”-我将首先进入这一部分,因为我想很多人都会来这里寻求答案。
可能有一个单独的问题。
在JavaScript中,变量可以由内部作用域重新定义,因此,假设环境尚未创建名为process,global或window的变量,则很容易失败,例如,如果使用的是node.js
jsdom模块,则该API使用示例将
var window = doc.defaultView;
此后,window
在该范围内运行的任何模块都将基于变量的存在检测环境会系统地失败。使用相同的逻辑,任何基于浏览器的代码都可以轻松覆盖global
或process
,因为它们不是该环境中的保留变量。
幸运的是,有一种方法需要全局范围并测试它的含义-如果使用new Function()
构造函数创建新函数,则的执行范围将this
绑定到全局范围,并且可以将全局范围直接与期望值进行比较。*)
因此,要创建一个函数,请检查全局范围是否为“ window”
var isBrowser=new Function("try {return this===window;}catch(e){ return false;}");
// tests if global scope is binded to window
if(isBrowser()) console.log("running under browser");
测试全局sope是否绑定到“ global”的函数将是
var isNode=new Function("try {return this===global;}catch(e){return false;}");
// tests if global scope is binded to "global"
if(isNode()) console.log("running under node.js");
try … catch -part将确保如果未定义变量,false
则返回该变量。
该isNode()
还可以比较this.process.title==="node"
或其他一些全球范围内可变发现里面的node.js如果你愿意,但相较于全球应该在实践中是不够的。
http://jsfiddle.net/p6yedbqk/
注意 :不建议检测运行环境。但是,它在特定的环境(例如具有全球范围内某些已知特征的开发和测试环境)中很有用。
现在-答案的第二部分。 在完成环境检测之后,您可以选择要使用的基于环境的策略(如果有)将“全局”变量绑定到应用程序。
我认为,这里推荐的策略是使用单例模式将您的设置绑定到类中。SO中已经有很多替代方案
在JavaScript中实现单例的最简单/最简洁的方法?
因此,事实证明,如果您不需要“全局”变量,并且根本不需要环境检测,只需使用单例模式定义一个模块即可为您存储值。好的,可以说模块本身是一个全局变量,实际上在JavaScript中是全局变量,但是至少从理论上讲,它看起来更干净一些。
*)https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function
注意:使用Function构造函数创建的函数不会创建其创建上下文的闭包。它们总是在全局范围内创建。运行它们时,它们将只能访问自己的局部变量和全局变量,而不能访问调用Function构造函数的作用域中的局部变量和全局变量。
问题内容: 我见过的大多数实现都是在客户端进行浏览器检测。我只是想知道是否有可能在将任何资源发送到客户端之前进行浏览器检测。 谢谢。 问题答案: 那应该为您工作。只需将其放在响应处理程序中即可。
问题内容: 是否可以从httpsession对象(javax.servlet.http.HttpSession)派生首选语言?可以从servletrequest中获取它,但我没有。感谢您的任何想法。斯文 问题答案: 用户的首选语言环境可以用作请求标头(“接受语言”)。它由用户的浏览器根据其首选项自动填充。然后,您可以将此信息存储在用户的会话中,并在以后适当时检索它。
JavaScript 语言最初是为 Web 浏览器创建的。此后,它已经发展成为一种具有多种用途和平台的语言。 平台可以是一个浏览器,一个 Web 服务器,或其他 主机(host),甚至可以是一个“智能”咖啡机,如果它能运行 JavaScript 的话。它们每个都提供了特定于平台的功能。JavaScript 规范将其称为 主机环境。 主机环境提供了自己的对象和语言核心以外的函数。Web 浏览器提供了
JavaScript 是浏览器的内置脚本语言。也就是说,浏览器内置了 JavaScript 引擎,并且提供各种接口,让 JavaScript 脚本可以控制浏览器的各种功能。一旦网页内嵌了 JavaScript 脚本,浏览器加载网页,就会去执行脚本,从而达到操作浏览器的目的,实现网页的各种动态效果。 本章开始介绍浏览器提供的各种 JavaScript 接口。首先,介绍 JavaScript 代码嵌入
问题内容: Javascript如何检测网站是加载到Android的常规浏览器中还是加载到另一个应用程序的WebView中?我想在这两种情况下运行略有不同的代码。 问题答案: 活动- > onCreate RES- >值-> strings.xml Java脚本
问题内容: 如何使用JavaScript检测Safari浏览器?我在下面尝试过代码,它不仅可以检测Safari,还可以检测Chrome浏览器。 问题答案: 您可以轻松地使用Chrome的索引来过滤掉Chrome: