背景
在瀏覽器中訪問本地靜態(tài)資源html網頁時,可能會遇到跨域問題如圖。
?
是因為瀏覽器默認啟用了同源策略,即只允許加載與當前網頁具有相同源(協(xié)議、域名和端口)的內容。
WebView2默認情況下啟用了瀏覽器的同源策略,即只允許加載與主機相同源的內容。所以如果我們把靜態(tài)資源發(fā)布到iis或者通過node進行啟動就可以看到不跨域了。
解決方案
-
使用CORS(Cross-Origin Resource Sharing):如果你有控制服務器端,可以在服務器端配置CORS來允許跨域請求。在服務器端的響應頭中添加相關的CORS頭部信息,例如允許訪問的域名、請求方法等,以允許JavaScript跨域訪問。
- 使用WebView2的
AddWebResourceRequestedFilter
方法:通過添加Web資源請求過濾器,你可以攔截WebView2控件中加載的資源請求,并進行處理。在攔截到JavaScript文件請求時,修改響應頭部信息,添加Access-Control-Allow-Origin
頭部來解決跨域問題。 - 使用代理服務器:你可以在本地啟動一個代理服務器,將WebView2控件的請求轉發(fā)到代理服務器上,然后代理服務器再將請求發(fā)送到原始服務器并返回響應。在代理服務器上你可以設置合適的CORS頭部信息來解決跨域問題。
思路
-
首先,確保你已經安裝了
Microsoft.Web.WebView2
。你可以在Visual Studio的NuGet包管理器中搜索并安裝此包。 - 然后通過HttpListener進行文件夾的靜態(tài)資源進行代理發(fā)布
- 然后通過webview2進行導航訪問即可我們會發(fā)現跨域問題已經解決
?
代碼
?
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WinApp.View { public partial class Cors : Form { // 創(chuàng)建HttpListener對象并指定綁定的端口 HttpListener _listener; string _folderPath; string _rootDirectory; public Cors() { InitializeComponent(); // 初始化 InitializeAsync(); } private async void InitializeAsync() { // 獲取本地靜態(tài)資源的路徑 _rootDirectory = AppDomain.CurrentDomain.BaseDirectory + "offline-exam-player"; //設置本地離線播放器為代理服務 _rootDirectory = @"C:\Users\admin\Documents\WeChat Files\wxid_1ofgk575ybpt22\FileStorage\File\2024-02\ng-alain8\ng-alain8/"; _folderPath = @"C:\Users\admin\Documents\WeChat Files\wxid_1ofgk575ybpt22\FileStorage\File\2024-02\ng-alain8\ng-alain8/index.html"; _listener = new HttpListener(); // 設置代理服務器的監(jiān)聽地址和端口號 _listener.Prefixes.Add("http://localhost:8080/"); _listener.Start(); // 啟動代理服務器 Task.Run(() => { // 啟動代理服務器 ProcessRequests(); }); // 停止代理服務器(這里演示就不停止了) //server.Stop(); } private void ProcessRequests() { try { while (_listener.IsListening) { HttpListenerContext context = _listener.GetContext(); string requestPath = context.Request.Url.AbsolutePath; string filePath = _rootDirectory + requestPath; // Serve the requested file if it exists if (System.IO.File.Exists(filePath)) { string extension = System.IO.Path.GetExtension(filePath); string contentType; switch (extension) { case ".html": contentType = "text/html"; break; case ".js": contentType = "application/javascript"; break; case ".less": case ".css": contentType = "text/css"; break; case ".svg": contentType = "image/svg+xml"; break; default: contentType = "application/octet-stream"; break; } context.Response.ContentType = contentType; //context.Response.ContentType = "text/html"; byte[] responseBuffer = System.IO.File.ReadAllBytes(filePath); context.Response.OutputStream.Write(responseBuffer, 0, responseBuffer.Length); context.Response.Close(); } else { // Return a 404 response if the file does not exist context.Response.StatusCode = 404; context.Response.Close(); } } } catch (Exception ex) { // Handle any exceptions that may occur Console.WriteLine(ex.ToString()); } } private async void Cors_Load(object sender, EventArgs e) { //本地靜態(tài)資源,直接訪問會出現跨院,如果通過iis訪問則不會跨域; // 確保CoreWebView2運行時已準備就緒 await webView21.EnsureCoreWebView2Async(); // 在WebView2控件中加載URL //webView21.CoreWebView2.Navigate(_folderPath); webView21.CoreWebView2.Navigate("http://localhost:8080/" + "index.html"); } } }
?
代理服務幫助類代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace WinApp.Until { public class ProxyHelper { private readonly HttpListener _listener; private readonly string _rootDirectory; /// <summary> /// 實例化 /// </summary> /// <param name="serviceIp">代理的ip地址帶端口,例子:http://localhost:8080/ </param> /// <param name="folderPath">需要代理的文件夾,例子:AppDomain.CurrentDomain.BaseDirectory + "offline-exam-player" </param> public ProxyHelper(string serviceIp, string folderPath) { _rootDirectory = folderPath; _listener = new HttpListener(); _listener.Prefixes.Add(serviceIp); } public async Task Start() { _listener.Start(); await Task.Run(() => ProcessRequests()); } public void Stop() { _listener.Stop(); _listener.Close(); Console.WriteLine("Proxy server stopped."); } private void ProcessRequests() { try { while (_listener.IsListening) { HttpListenerContext context = _listener.GetContext(); string requestPath = context.Request.Url.AbsolutePath; string filePath = _rootDirectory + requestPath; // Serve the requested file if it exists if (System.IO.File.Exists(filePath)) { string extension = System.IO.Path.GetExtension(filePath); string contentType; switch (extension) { case ".html": contentType = "text/html"; break; case ".js": contentType = "application/javascript"; break; case ".less": case ".css": contentType = "text/css"; break; case ".svg": contentType = "image/svg+xml"; break; default: contentType = "application/octet-stream"; break; } context.Response.ContentType = contentType; //context.Response.ContentType = "text/html"; byte[] responseBuffer = System.IO.File.ReadAllBytes(filePath); context.Response.OutputStream.Write(responseBuffer, 0, responseBuffer.Length); context.Response.Close(); } else { // Return a 404 response if the file does not exist context.Response.StatusCode = 404; context.Response.Close(); } } } catch (Exception ex) { // Handle any exceptions that may occur Console.WriteLine(ex.ToString()); } } } }
?文章來源:http://www.zghlxwxcb.cn/news/detail-833132.html
結語
最后如果對于不多的跨域js文件,可以把js的代碼內嵌到index.html頁面實現。就是<script>跨域js內容</script>文章來源地址http://www.zghlxwxcb.cn/news/detail-833132.html
到了這里,關于c#使用webView2 訪問本地靜態(tài)html資源跨域Cors問題 (附帶代理服務helper幫助類)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!