在本地HTML文件中通过
我在InfinityFree上创建了一个测试网站,并上传了一个测试文件,用来在一个 <iframe\> 中显示一个YouTube视频。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Local Video Embed Test</title>
</head>
<body>
<h1>My Local Web Page</h1>
<!-- Paste your copied YouTube iframe code here -->
<iframe width="560" height="315"
src="https://www.youtube.com/embed/1IxxwvR6qSA?si=GjL_9UnP4EtQJTHs"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen>
</iframe>
</body>
</html>
这按预期工作。问题出现在我把它作为本地文件在桌面上打开时,浏览器打开后就无法观看视频。我得到一个“Error 153 Video player configuration”的错误。Google AI模式告诉我可以这样做,但并没有成功。这真的可能吗?我知道这在PDF和 Word文档中可以实现。对我来说,创建包含嵌入式YouTube视频的本地HTML文档会非常有用。
解决方案
只要不要导航到文件URI就行。通常可以在导航到原始文件内容(而不是把本地资源作为本地资源去导航)时,或将本地资源映射成一个虚拟主机,从而绕过file:// 本地资源来源的问题,或不透明来源的问题。
大多数浏览器并不将本地文件视为安全源。它们将其归类为不安全的来源,并且是一个不透明的来源。
关于不透明来源,浏览器AI的解释:
不透明来源是浏览器内部的安全值,用于遮蔽或使资源的真实来源失效,确保它永远不会被视为与任何其他来源相等,包括其他不透明来源。当资源的来源敏感、不存在,或对标准安全检查不安全时,例如沙箱内的iframe、file:// URL,或通过API(如DOMImplementation.createDocument())创建的文档,就会将其序列化为null并应用。
因此,YouTube只会看到NULL作为站点来源,并将其视为可疑。
正常托管页面:
Parent URL: http://127.0.0.1:5500/testvideo.html
Origin: http://127.0.0.1:5500
YouTube看到的是一个正常的网页来源。
本地文件页面:
Parent URL: file:///C:/.../testvideo.html
Origin: null / opaque / not a normal web origin
YouTube看到的不是一个可接受的托管来源。
方案1
使用 File.ReadAllTextAsync 将HTML文件读取为字符串,然后使用 WebView2 导航到原始文件内容。
简单来说,
string htmlFilePath = "path/to/testvideo.html";
string htmlContent = await File.ReadAllTextAsync(htmlFilePath);
// Call this line once in your application
// to properly initialise the control
await webView.EnsureCoreWebView2Async()
// Navigate to raw HTML
_webView2.NavigateToString(htmlContent);
这对你的小型HTML应该管用。但你需要知道 WebView2.NavigateToString 的文件大小限制为2 MB。对于简单的HTML,这个限制通常足够。但对于可能内联大量脚本的巨大文件,可能会超过这个限制。
对于 WebView2.NavigateToString 方法的文档指出:
htmlContent参数的总大小不得超过2 MB(2×1024×1024字节)。新页面的来源为about:blank。
方案2
另一种避免2 MB限制的替代方案是将文件资源映射到一个虚拟主机名:
// Call this line once in your application
// to properly initialise the control
await webView.EnsureCoreWebView2Async();
// Example based on Microsoft Docs
string htmlRootDirectory = "path/to/html/location";
webView.CoreWebView2.SetVirtualHostNameToFolderMapping(
"appassets.example", "htmlRootDirectory", CoreWebView2HostResourceAccessKind.DenyCors);
webView.Source = new Uri("https://appassets.example/testvideo.html");
如你所见,映射让你在导航本地文件时就像访问一个已托管的远程资源一样。被映射的文件现在由指定的虚拟主机虚拟托管(这里 appassets.example)。
appassets.example 指向包含HTML文件的目录。现在,你可以使用主机URL来导航到该映射目录中的任意HTML文件。
有关虚拟主机名映射的更多备注,请参阅 Microsoft Docs。