使用 CSS/JS 从服务器磁盘到客户端浏览器呈现并提供 HTML 文件
Render and serve HTML file with CSS/JS from server disk to Client Browser
我遇到了一个问题,简单来说,就是找到一种方法来安全地呈现和提供 HTML 文件(以及 CSS、JS)从服务器中的本地磁盘到客户端浏览器中的 Web 应用程序 运行。
应用
- 前端 Web 应用程序是使用 React JS(准确地说是 react-admin)创建的。
- 处理 Rest API 请求的后端是使用 Net core 3.1
设置的
- 这两个应用程序都托管在 Windows 服务器的 IIS 中(作为 IIS 中默认网站内的应用程序服务)。
约束条件
- 应用程序的托管只能在 windows 服务器的 IIS 内部进行。 (也欢迎其他选项)
- 后端/前端可以是我们想要的任何语言。 (最好是 dot net core,因为我在过去 10 年一直使用 C#)
技术细节
我正在开发一个托管点云查看器的解决方案(Potree,一个使用 three-js 开发的开源项目)。这是一个独立的过程。 Potree 提供了一个基于桌面的 C++ 转换器,它将输入转换为网页(使用 html、css、js)(让我们将其称为目标文件 ).我们可以在任何服务器上托管此网页以供外部各方查看。
当前状态
工作:目标文件作为应用程序托管在 IIS 服务器中,可以毫无问题地访问它。 (图像可以在下面看到)。
工作: React js 网络应用程序已构建,dist 文件托管在 IIS 服务器中,也可以毫无问题地访问它。
以上两个步骤确认构建的应用程序运行良好,因为它们可以单独托管,也可以从其他计算机访问。
我坚持使用的功能
- 目标文件适用于不同的用户。因此,必须在通过 API 请求验证后提供服务。
- 当前设置是这样的,当用户在 React 应用程序中单击 link 时,它会进行 REST Api 调用,由后端 dotnet 核心应用程序处理(可能有其他更好的将 html 文件提供给前端 Web 应用程序的方法)。
我尝试了几种方法来提供 HTML 文件。
选项 1:使用 StaticFiles(在启动时)。我正在尝试从本地读取 html 文件,然后使用 @Html.Raw(Model.SomePropertyName)
在 noidea.cshtml 文件中渲染它
// GET: /<controller>/
public IActionResult noidea()
{
try
{
var newmodel = new noideaModel();
var file = System.IO.File.ReadAllLines("./acl-i/acl-i.html");
newmodel._html = string.Join("", file);
return View(newmodel);
//return View();
}
catch (Exception)
{
throw;
}
}
}
这个选项部分工作正常,但问题是因为我将文件放在静态文件夹中(在启动时配置)用户可以轻松更改 URL 并访问那里的其他文件。
因此,我尝试使用选项 2,即只从本地磁盘读取 html 文件的内容并将其作为内容结果提供。:
[AllowAnonymous]
[HttpGet, Route("viewer")]
public IActionResult getViewer()
{
//For serving single static html file.
var file = System.IO.File.ReadAllLines("./acl-i/acl-i.html");
var item = string.Join("", file);
return new ContentResult
{
ContentType = "text/html",
StatusCode = (int)StatusCodes.Status200OK,
Content = item
};
}
这里的成功点是,我能够正确验证并且用户无法更改 URL,因为 api 端点提供文件。
问题是我只提供 HTMl 和 linked css,客户端浏览器无法识别 js。下图显示了这个问题。 js和CSS也在同一个api端点被搜索
问题:
我是 React js 和 Web 前端开发的新手。我主要使用 Xamarin,C#/WPF/XML 用于桌面应用程序,并为 CRUD 应用程序开发 Web API 端点。所以,我完全被困在这里。不知道如何解决这个问题。
- 我正在寻找解决当前问题的方法。
- 或者找到一个优雅简单的方法来解决这个问题(我也看到了一些 express js 和 react js 的例子,但不清楚,我也是新手)。
我只需要找到一种方法来验证用户身份,然后为他提供一个完全呈现的 html 页面以在他的浏览器中查看(这听起来很容易以这种方式解释)任何帮助或指导/建议都将不胜感激。
我尝试了不同的方法来解决这个问题。最后,我找到了解决方案。 (可能不是最好的,但可能对也有类似问题的人有帮助)。
工作流程:
现在,我们每周都会从外部分包商那里收到几个构建的网页。我们的分包商使用 Potree Converter 将他们的点云数据转换为网页(其中有几个 html、js、css)压缩成大约 2-3 GB 的文件(由于点云的大小数据)。不可能一次性将所有文件下载到客户端浏览器。这是由 potree 网页本身处理的。根据用户浏览,html 页面抓取部分数据并频繁发送。但是,我们不必担心它,因为它完全由 Potree 开发团队管理(感谢维也纳工业大学计算机图形与算法研究所)
因此,我们无法对从分包商那里收到的 html 网站做很多事情。我们的工作是托管并为利益相关者提供安全访问。
应用程序:
最初我开发了两个应用程序,还有一个从 Potree 转换器转换的 html 页面。
- React JS 网络应用程序:用作前端(让我们调用应用程序 1)
- dot net core 3.1 后端:用于处理 API 请求。 (让我们调用 App 2)
此项目托管在 IIS 中。因此,我创建了一个新站点(运行 在防火墙后面的不同端口上并且不暴露给外部各方)。我们称其为 目标站点
通过 IIS 反向代理设置
- 我们在 IIS 中(通过 ARR)为所有传入请求设置了一个反向代理。
- IIS 将过滤在 URL 中具有特定字符串的传入 URL。 (例如, /5506f977-7463-4f85-86ff-7ca63bac34fa/ ,假设 url_guid)。
- URL 重写将改变这一点并直接到目标站点(运行 在防火墙后面的不同端口上)
**目标文件设置**
每次我们从分包商那里收到新的目标页面(转换后的 zip 文件)时,我们都会获取 index.html 文件,用 GUID (target_file_GUID) 重命名它,添加一个标记到 header 以包含 url_guid 并将其放在公共目录中。
我们将 target_file_GUID 添加到我们的 Mysql 数据库 table 的列中,其中还有一个列用于存储文件的实际名称。
解决方案
- 我们从应用程序 1 向应用程序 2 发送请求(在 header 秒内使用 JWT 身份验证和所需的 HTML 文件(或点云模型))。
- 验证后,我们从MYSQL
中获取相应html文件的guid名称
- 然后从公共目录中获取此特定文件并发送到浏览器。
- 在这一点上,浏览器 URL 仍然没有改变并且包含相同的 URL 用于访问 API 控制器。
- 加载 Html 文件时,它还会尝试加载 html 中提到的 CSS 所需的 JS 文件。诀窍就发生在这里。由于我们指定了标签,新的 url 请求被发送到服务器,被 IIS 拦截并重写到内部服务器。 (此时客户端浏览器中的URL仍然没有因为服务端Rewrite而改变)
- 客户端浏览器收到 JS,CSS 文件(但客户端浏览器中仍然 URL 并且请求 headers 没有显示实际 URL ).
结论
我为写了一个很长的回复而没有太多代码而道歉。整个设置和想法花了更多的时间来构思(可能还有更好的方法来处理它。我不知道)。
这里的主要成就是
- 在将用户引导至不同 URL 之前授权用户。
- URL Rewrite 不向客户端浏览器显示原始 url
- 原始目标站点仍受防火墙保护
- html 的原始文件名被 GUID 替换(用户很难猜到)并且这个 html guid 名称通过 windows 服务重复更改每周控制台应用程序。 (假设我们总共有 1000 个文件。名称每周都会更改以确保其安全和自信)。
- 用户无法直接访问 html 文件(即使他知道文件的名称。因为这仅在身份验证后通过 App 2 提供)
或多或少,我们认为在这一点上已经足够安全,可以继续进行下去了。如果其他人面临类似问题并取得了不同的解决方案,请分享。
我遇到了一个问题,简单来说,就是找到一种方法来安全地呈现和提供 HTML 文件(以及 CSS、JS)从服务器中的本地磁盘到客户端浏览器中的 Web 应用程序 运行。
应用
- 前端 Web 应用程序是使用 React JS(准确地说是 react-admin)创建的。
- 处理 Rest API 请求的后端是使用 Net core 3.1 设置的
- 这两个应用程序都托管在 Windows 服务器的 IIS 中(作为 IIS 中默认网站内的应用程序服务)。
约束条件
- 应用程序的托管只能在 windows 服务器的 IIS 内部进行。 (也欢迎其他选项)
- 后端/前端可以是我们想要的任何语言。 (最好是 dot net core,因为我在过去 10 年一直使用 C#)
技术细节
我正在开发一个托管点云查看器的解决方案(Potree,一个使用 three-js 开发的开源项目)。这是一个独立的过程。 Potree 提供了一个基于桌面的 C++ 转换器,它将输入转换为网页(使用 html、css、js)(让我们将其称为目标文件 ).我们可以在任何服务器上托管此网页以供外部各方查看。
当前状态
工作:目标文件作为应用程序托管在 IIS 服务器中,可以毫无问题地访问它。 (图像可以在下面看到)。
工作: React js 网络应用程序已构建,dist 文件托管在 IIS 服务器中,也可以毫无问题地访问它。
以上两个步骤确认构建的应用程序运行良好,因为它们可以单独托管,也可以从其他计算机访问。
我坚持使用的功能
- 目标文件适用于不同的用户。因此,必须在通过 API 请求验证后提供服务。
- 当前设置是这样的,当用户在 React 应用程序中单击 link 时,它会进行 REST Api 调用,由后端 dotnet 核心应用程序处理(可能有其他更好的将 html 文件提供给前端 Web 应用程序的方法)。
我尝试了几种方法来提供 HTML 文件。 选项 1:使用 StaticFiles(在启动时)。我正在尝试从本地读取 html 文件,然后使用
在 noidea.cshtml 文件中渲染它@Html.Raw(Model.SomePropertyName)
// GET: /<controller>/ public IActionResult noidea() { try { var newmodel = new noideaModel(); var file = System.IO.File.ReadAllLines("./acl-i/acl-i.html"); newmodel._html = string.Join("", file); return View(newmodel); //return View(); } catch (Exception) { throw; } }
}
这个选项部分工作正常,但问题是因为我将文件放在静态文件夹中(在启动时配置)用户可以轻松更改 URL 并访问那里的其他文件。
因此,我尝试使用选项 2,即只从本地磁盘读取 html 文件的内容并将其作为内容结果提供。:
[AllowAnonymous]
[HttpGet, Route("viewer")]
public IActionResult getViewer()
{
//For serving single static html file.
var file = System.IO.File.ReadAllLines("./acl-i/acl-i.html");
var item = string.Join("", file);
return new ContentResult
{
ContentType = "text/html",
StatusCode = (int)StatusCodes.Status200OK,
Content = item
};
}
这里的成功点是,我能够正确验证并且用户无法更改 URL,因为 api 端点提供文件。 问题是我只提供 HTMl 和 linked css,客户端浏览器无法识别 js。下图显示了这个问题。 js和CSS也在同一个api端点被搜索
问题:
我是 React js 和 Web 前端开发的新手。我主要使用 Xamarin,C#/WPF/XML 用于桌面应用程序,并为 CRUD 应用程序开发 Web API 端点。所以,我完全被困在这里。不知道如何解决这个问题。
- 我正在寻找解决当前问题的方法。
- 或者找到一个优雅简单的方法来解决这个问题(我也看到了一些 express js 和 react js 的例子,但不清楚,我也是新手)。
我只需要找到一种方法来验证用户身份,然后为他提供一个完全呈现的 html 页面以在他的浏览器中查看(这听起来很容易以这种方式解释)任何帮助或指导/建议都将不胜感激。
我尝试了不同的方法来解决这个问题。最后,我找到了解决方案。 (可能不是最好的,但可能对也有类似问题的人有帮助)。
工作流程: 现在,我们每周都会从外部分包商那里收到几个构建的网页。我们的分包商使用 Potree Converter 将他们的点云数据转换为网页(其中有几个 html、js、css)压缩成大约 2-3 GB 的文件(由于点云的大小数据)。不可能一次性将所有文件下载到客户端浏览器。这是由 potree 网页本身处理的。根据用户浏览,html 页面抓取部分数据并频繁发送。但是,我们不必担心它,因为它完全由 Potree 开发团队管理(感谢维也纳工业大学计算机图形与算法研究所)
因此,我们无法对从分包商那里收到的 html 网站做很多事情。我们的工作是托管并为利益相关者提供安全访问。
应用程序: 最初我开发了两个应用程序,还有一个从 Potree 转换器转换的 html 页面。
- React JS 网络应用程序:用作前端(让我们调用应用程序 1)
- dot net core 3.1 后端:用于处理 API 请求。 (让我们调用 App 2)
此项目托管在 IIS 中。因此,我创建了一个新站点(运行 在防火墙后面的不同端口上并且不暴露给外部各方)。我们称其为 目标站点
通过 IIS 反向代理设置
- 我们在 IIS 中(通过 ARR)为所有传入请求设置了一个反向代理。
- IIS 将过滤在 URL 中具有特定字符串的传入 URL。 (例如, /5506f977-7463-4f85-86ff-7ca63bac34fa/ ,假设 url_guid)。
- URL 重写将改变这一点并直接到目标站点(运行 在防火墙后面的不同端口上)
**目标文件设置**
每次我们从分包商那里收到新的目标页面(转换后的 zip 文件)时,我们都会获取 index.html 文件,用 GUID (target_file_GUID) 重命名它,添加一个标记到 header 以包含 url_guid 并将其放在公共目录中。
我们将 target_file_GUID 添加到我们的 Mysql 数据库 table 的列中,其中还有一个列用于存储文件的实际名称。
解决方案
- 我们从应用程序 1 向应用程序 2 发送请求(在 header 秒内使用 JWT 身份验证和所需的 HTML 文件(或点云模型))。
- 验证后,我们从MYSQL 中获取相应html文件的guid名称
- 然后从公共目录中获取此特定文件并发送到浏览器。
- 在这一点上,浏览器 URL 仍然没有改变并且包含相同的 URL 用于访问 API 控制器。
- 加载 Html 文件时,它还会尝试加载 html 中提到的 CSS 所需的 JS 文件。诀窍就发生在这里。由于我们指定了标签,新的 url 请求被发送到服务器,被 IIS 拦截并重写到内部服务器。 (此时客户端浏览器中的URL仍然没有因为服务端Rewrite而改变)
- 客户端浏览器收到 JS,CSS 文件(但客户端浏览器中仍然 URL 并且请求 headers 没有显示实际 URL ).
结论 我为写了一个很长的回复而没有太多代码而道歉。整个设置和想法花了更多的时间来构思(可能还有更好的方法来处理它。我不知道)。
这里的主要成就是
- 在将用户引导至不同 URL 之前授权用户。
- URL Rewrite 不向客户端浏览器显示原始 url
- 原始目标站点仍受防火墙保护
- html 的原始文件名被 GUID 替换(用户很难猜到)并且这个 html guid 名称通过 windows 服务重复更改每周控制台应用程序。 (假设我们总共有 1000 个文件。名称每周都会更改以确保其安全和自信)。
- 用户无法直接访问 html 文件(即使他知道文件的名称。因为这仅在身份验证后通过 App 2 提供)
或多或少,我们认为在这一点上已经足够安全,可以继续进行下去了。如果其他人面临类似问题并取得了不同的解决方案,请分享。