夕颜花开 发表于 2024-2-20 20:00:05

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

背景

在浏览器中访问本地静态资源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进行导航访问即可我们会发现跨域问题已经解决
 
代码

 
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
    {
      // 创建HttpListener对象并指定绑定的端口
      HttpListener _listener;
      string _folderPath;
      string _rootDirectory;

      public Cors()
      {
            InitializeComponent();

            // 初始化
            InitializeAsync();
      }

      private async void InitializeAsync()
      {
            // 获取本地静态资源的路径            
            _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();
            // 设置代理服务器的监听地址和端口号
            _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)
      {
            //本地静态资源,直接访问会出现跨院,如果通过iis访问则不会跨域;

            // 确保CoreWebView2运行时已准备就绪
            await webView21.EnsureCoreWebView2Async();

            // 在WebView2控件中加载URL
            //webView21.CoreWebView2.Navigate(_folderPath);            
            webView21.CoreWebView2.Navigate("http://localhost:8080/" + "index.html");
      }

    }

结语

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

来源:https://www.cnblogs.com/BFMC/p/18022948
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: c#使用webView2 访问本地静态html资源跨域Cors问题