翼度科技»论坛 编程开发 .net 查看内容

c#使用webView2 访问本地静态html资源跨域Cors问题

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
背景

在浏览器中访问本地静态资源html网页时,可能会遇到跨域问题如图。

 
是因为浏览器默认启用了同源策略,即只允许加载与当前网页具有相同源(协议、域名和端口)的内容。
WebView2默认情况下启用了浏览器的同源策略,即只允许加载与主机相同源的内容。所以如果我们把静态资源发布到iis或者通过node进行启动就可以看到不跨域了。
解决方案


  • 使用CORS(Cross-Origin Resource Sharing):如果你有控制服务器端,可以在服务器端配置CORS来允许跨域请求。在服务器端的响应头中添加相关的CORS头部信息,例如允许访问的域名、请求方法等,以允许JavaScript跨域访问。
  • 使用WebView2的 AddWebResourceRequestedFilter 方法:通过添加Web资源请求过滤器,你可以拦截WebView2控件中加载的资源请求,并进行处理。在拦截到JavaScript文件请求时,修改响应头部信息,添加Access-Control-Allow-Origin头部来解决跨域问题。
  • 使用代理服务器:你可以在本地启动一个代理服务器,将WebView2控件的请求转发到代理服务器上,然后代理服务器再将请求发送到原始服务器并返回响应。在代理服务器上你可以设置合适的CORS头部信息来解决跨域问题。
思路


  • 首先,确保你已经安装了Microsoft.Web.WebView2。你可以在Visual Studio的NuGet包管理器中搜索并安装此包。
  • 然后通过HttpListener进行文件夹的静态资源进行代理发布
  • 然后通过webview2进行导航访问即可我们会发现跨域问题已经解决

     
代码

 
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using System.Windows.Forms;
  11. namespace WinApp.View
  12. {
  13.     public partial class Cors : Form
  14.     {
  15.         // 创建HttpListener对象并指定绑定的端口
  16.         HttpListener _listener;
  17.         string _folderPath;
  18.         string _rootDirectory;
  19.         public Cors()
  20.         {
  21.             InitializeComponent();
  22.             // 初始化
  23.             InitializeAsync();
  24.         }
  25.         private async void InitializeAsync()
  26.         {
  27.             // 获取本地静态资源的路径            
  28.             _rootDirectory = AppDomain.CurrentDomain.BaseDirectory + "offline-exam-player"; //设置本地离线播放器为代理服务
  29.             _rootDirectory = @"C:\Users\admin\Documents\WeChat Files\wxid_1ofgk575ybpt22\FileStorage\File\2024-02\ng-alain8\ng-alain8/";
  30.             _folderPath = @"C:\Users\admin\Documents\WeChat Files\wxid_1ofgk575ybpt22\FileStorage\File\2024-02\ng-alain8\ng-alain8/index.html";
  31.             _listener = new HttpListener();
  32.             // 设置代理服务器的监听地址和端口号
  33.             _listener.Prefixes.Add("http://localhost:8080/");
  34.             _listener.Start();
  35.             // 启动代理服务器
  36.             Task.Run(() =>
  37.             {
  38.                 // 启动代理服务器
  39.                 ProcessRequests();
  40.             });
  41.             // 停止代理服务器(这里演示就不停止了)
  42.             //server.Stop();
  43.         }
  44.         private void ProcessRequests()
  45.         {
  46.             try
  47.             {
  48.                 while (_listener.IsListening)
  49.                 {
  50.                     HttpListenerContext context = _listener.GetContext();
  51.                     string requestPath = context.Request.Url.AbsolutePath;
  52.                     string filePath = _rootDirectory + requestPath;
  53.                     // Serve the requested file if it exists
  54.                     if (System.IO.File.Exists(filePath))
  55.                     {
  56.                         string extension = System.IO.Path.GetExtension(filePath);
  57.                         string contentType;
  58.                         switch (extension)
  59.                         {
  60.                             case ".html":
  61.                                 contentType = "text/html";
  62.                                 break;
  63.                             case ".js":
  64.                                 contentType = "application/javascript";
  65.                                 break;
  66.                             case ".less":
  67.                             case ".css":
  68.                                 contentType = "text/css";
  69.                                 break;
  70.                             case ".svg":
  71.                                 contentType = "image/svg+xml";
  72.                                 break;
  73.                             default:
  74.                                 contentType = "application/octet-stream";
  75.                                 break;
  76.                         }
  77.                         context.Response.ContentType = contentType;
  78.                         //context.Response.ContentType = "text/html";
  79.                         byte[] responseBuffer = System.IO.File.ReadAllBytes(filePath);
  80.                         context.Response.OutputStream.Write(responseBuffer, 0, responseBuffer.Length);
  81.                         context.Response.Close();
  82.                     }
  83.                     else
  84.                     {
  85.                         // Return a 404 response if the file does not exist
  86.                         context.Response.StatusCode = 404;
  87.                         context.Response.Close();
  88.                     }
  89.                 }
  90.             }
  91.             catch (Exception ex)
  92.             {
  93.                 // Handle any exceptions that may occur
  94.                 Console.WriteLine(ex.ToString());
  95.             }
  96.         }
  97.         private async void Cors_Load(object sender, EventArgs e)
  98.         {
  99.             //本地静态资源,直接访问会出现跨院,如果通过iis访问则不会跨域;
  100.             // 确保CoreWebView2运行时已准备就绪
  101.             await webView21.EnsureCoreWebView2Async();
  102.             // 在WebView2控件中加载URL
  103.             //webView21.CoreWebView2.Navigate(_folderPath);            
  104.             webView21.CoreWebView2.Navigate("http://localhost:8080/" + "index.html");
  105.         }
  106.     }
  107. }
复制代码
 
结语

最后如果对于不多的跨域js文件,可以把js的代码内嵌到index.html页面实现。就是

来源:https://www.cnblogs.com/BFMC/p/18022948
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具