如何在后端服务器中检测客户端是否启用了/禁用了 JavaScript
学习如何在你的后端 Web 服务器上检测客户端是否启用了 JavaScript 或禁用了 JavaScript
引言
在这篇文章中,我将向您展示如何在后端 Web 服务器(任何平台)上检测客户端是否启用了 JavaScript,以便您可以在后端代码中使用它,并将其用作布尔值。
不幸的是,没有现成的方法可以检测到这一点。浏览器不会向 Web 服务器发送指示浏览器是否启用了 JavaScript 的 HTTP 标头/元数据。
因此,要检测它,我们需要做一些手动工作。
如何操作
后端代码
检测的技巧是,在客户端浏览器中设置一个标志(一个 cookie),指示浏览器是否启用了/禁用了 JavaScript。
然后服务器可以查看该 cookie,并检查客户端是否通过 JavaScript 指示其 JavaScript 已启用/禁用。
在此示例中,我们将其称为 cookie hasjs=false
。因此,如果客户端拥有名为 hasjs
的 cookie 且其值为 false
,则表示客户端指示 JavaScript 已关闭,否则 JavaScript 已开启。
因此,对于每个 webrequest
,在您的后端服务器中创建一个布尔变量,并将其命名为 IsJavascriptOn
,如果客户端拥有 cookie hasjs=false
,则将其设置为 false
,否则将其设置为 true
。
我将使用 ASP.NET MVC 作为代码示例,但概念对于所有平台都相同。
下面是一个函数示例,如果客户端拥有 cookie hasjs=false
,则返回 false
,否则返回 true
。
bool GetIsJavascriptOn()
{
//If client has the cookie with name and value: hasjs=false
if (Request.Cookies.ContainsKey("hasjs") &&
Request.Cookies["hasjs"] == "false")
return false;
else //Client doesn't have the cookie: hasjs=false
return true;
}
然后,在我们的代码中的某个位置,我们可以像下面这样设置我们的 IsJavascriptOn
变量
this.IsJavascriptOn = GetIsJavascriptOn();
现在,我们有了确定客户端是否启用了/禁用了 JavaScript 的布尔变量,所以现在我们可以在后端代码的任何地方使用这个变量了。
渲染 HTML
因此,现在我们需要在 JavaScript 被禁用时设置 hasjs=false
cookie,在 JavaScript 被启用时删除 hasjs=false
cookie。这在渲染 HTML 时完成。
我们需要根据客户端指示 JavaScript 是否启用/禁用来渲染一些 HTML。下面显示了这一点。
我们将此代码放在 <head> 中
<!--If client indicates that javascript is enabled (cookie "hasjs=false" doesn't exist)-->
@if (Model.IsJavascriptOn == true)
{
<noscript>
<meta http-equiv="Set-Cookie" content="hasjs=false; path=/">
<meta http-equiv="Refresh" content="0">
</noscript>
}
else //Client indicates javascript is disabled (cookie "hasjs=false" exists)
{
<script>
document.cookie = "hasjs=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
location.reload(true); //Refreshes the page
</script>
}
现在我们完成了。如果您只想测试它而不想要任何解释,可以跳过其余部分。
在这里,如果我们的变量 IsJavascriptOn
等于 true
,我们则绘制 <noscript> 块,否则我们绘制 <script>
块。
<noscript>
块将设置 cookie hasjs=false
,然后刷新页面(是的,您可以在没有 JavaScript 的情况下设置 cookie 并刷新页面)。
<script>
块将删除 cookie hasjs=false
,然后刷新页面。
所以这里发生的是,如果客户端指示 JavaScript 已开启,那么我们绘制 <noscript>
块。但客户端不会运行 <noscript>
块,除非它实际上被禁用了。
所以,如果它运行了 <noscript>
块,那么这意味着客户端告诉服务器它启用了 JavaScript,但这是错误的,需要将 hasjs
更新/设置为 false
,然后刷新页面。
完成后,服务器将改为渲染 <script>
块,然后直到客户端再次启用 JavaScript,客户端才会运行 <script>
块。
因此,当客户端再次启用 JavaScript 时,客户端将运行 <script>
块,删除 cookie hasjs
并刷新页面。
然后,服务器将绘制 <noscript>
块,然后直到客户端再次禁用 JavaScript,客户端才会运行该块。
这就是循环的过程。
ASP.NET MVC 完整示例
这是 ASP.NET Core MVC(.NET Framework)中的完整示例。它非常直接,所以希望非 ASP.NET 程序员也能理解它,因为它几乎就像伪代码。
在此示例中,我将展示一个具有 3 个页面(index(主页
)、contact 和 about)的最小网站,不带 CSS。
HomeController.cs
当客户端请求特定路径的页面时,此文件是代码开始的地方。它将检查客户端是否拥有 hasjs=false
cookie,如果存在,则将我们的 IsJavascriptOn
变量设置为 false
,否则设置为 true
。
using Microsoft.AspNetCore.Mvc;
namespace WebApplication1
{
public class ViewDataModel
{
public bool IsJavascriptOn;
}
}
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public ViewDataModel ViewDataModel;
bool GetIsJavascriptOn()
{
//If client has the cookie with name and value: hasjs=false
if (Request.Cookies.ContainsKey("hasjs") &&
Request.Cookies["hasjs"] == "false")
return false;
else //Client doesn't have the cookie: hasjs=false
return true;
}
//Executed if path is: "/" or "/home"
public IActionResult Index()
{
this.ViewDataModel = new ViewDataModel();
this.ViewDataModel.IsJavascriptOn = this.GetIsJavascriptOn();
//draws the Index.cshtml in @RenderBody inside _Layout.cshtml
return View(this.ViewDataModel);
}
//Executed if path is: "/home/about"
public IActionResult About()
{
this.ViewDataModel = new ViewDataModel();
this.ViewDataModel.IsJavascriptOn = this.GetIsJavascriptOn();
//draws the About.cshtml in @RenderBody inside _Layout.cshtml
return View(this.ViewDataModel);
}
//Executed if path is: "/home/about"
public IActionResult Contact()
{
this.ViewDataModel = new ViewDataModel();
this.ViewDataModel.IsJavascriptOn = this.GetIsJavascriptOn();
//draws the Contact.cshtml in @RenderBody inside _Layout.cshtml
return View(this.ViewDataModel);
}
}
}
_Layout.cshtml
这是渲染 HTML 的起点。_Layout
是无论我们在哪个页面都会被渲染的内容,然后它会触发 @RenderBody()
,这是一个 ASP.NET MVC 函数,它将渲染我们所在的页面。在本例中,这将渲染 index.cshtml、contact.cshtml 或 about.cshtml。
@model ViewDataModel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Detect_Javascript</title>
<!--If client indicates that javascript is enabled (cookie "hasjs=false" doesn't exist)-->
@if (Model.IsJavascriptOn == true)
{
<noscript>
<meta http-equiv="Set-Cookie" content="hasjs=false; path=/">
<meta http-equiv="Refresh" content="0">
</noscript>
}
else //Client indicates javascript is disabled (cookie "hasjs=false" exists)
{
<script>
document.cookie = "hasjs=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
location.reload(true); //Refreshes the page
</script>
}
</head>
<body>
<ul>
<li><a href="/home">Home</a></li>
<li><a href="/home/about">About</a></li>
<li><a href="/home/contact">Contact</a></li>
</ul>
@RenderBody()
</body>
</html>
Index.cshtml
@model ViewDataModel
<h1>Home page</h1>
<p>This is the home page</p>
@if (Model.IsJavascriptOn == true)
{
<p>Javascript is enabled</p>
}
else
{
<p>Javascript is disabled</p>
}
Contact.cshtml
@model ViewDataModel
<h1>Contact page</h1>
<p>This is the contact page</p>
@if (Model.IsJavascriptOn == true)
{
<p>Javascript is enabled</p>
}
else
{
<p>Javascript is disabled</p>
}
About.cshtml
@model ViewDataModel
<h1>About page</h1>
<p>This is the about page</p>
@if (Model.IsJavascriptOn == true)
{
<p>Javascript is enabled</p>
}
else
{
<p>Javascript is disabled</p>
}
所以,在这里,如果您启用了 JavaScript,它将显示 是的,JavaScript 已启用
,否则显示 否,JavaScript 已禁用
。
下面是两个示例,展示了它应该是什么样子:
最后说明
在 <noscript>
标签内,<meta http-equiv="Set-Cookie" content="hasjs=false; path=/">
,将 path 设置为 "/"
非常重要,因为 cookie 可以有路径,所以如果您导航到网站上的不同路径/站点,客户端可能会创建许多不同的 hasjs=false
cookie,具体取决于客户端所在的路径。
感谢阅读,希望这对大家有所帮助。:-)