c#使用webView2 访问本地静态html资源跨域Cors问题 (附带代理服务helper帮助类)
背景
在浏览器中访问本地静态资源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");
} }
}
代理服务帮助类代码:
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());
}
}
}
}
结语
最后如果对于不多的跨域js文件,可以把js的代码内嵌到index.html页面实现。就是<script>跨域js内容</script>
c#使用webView2 访问本地静态html资源跨域Cors问题 (附带代理服务helper帮助类)的更多相关文章
- 访问本地json文件因跨域导致的问题
我使用jquery的getJSON的方法获取本地的json文件,并进行操作,获取json 数据代码如下: $.getJSON("invite_panel.json",functio ...
- vue-cli 项目优化之3种方法对比:本地静态库资源(推荐)、cdn、DllPlugin
vue-cli 项目优化之3种方法对比:本地静态库资源(推荐).cdn.DllPlugin 事项 本地静态库资源 cdn DllPlugin 依赖 依赖cdn网站资源(有种完善方法:如果cdn引入不成 ...
- nginx/apache静态资源跨域访问问题详解
1. apache静态资源跨域访问 找到apache配置文件httpd.conf 找到这行 #LoadModule headers_module modules/mod_headers.so把#注释符 ...
- IIS Manager 配置文件修该,允许跨域CORS访问
IIS Manager 配置文件修该,允许跨域CORS访问 IIS Manager 的api访问会出现跨域问题,需要 IIS Manager的配置文件中修改. 配置文件的路径:C:\Program F ...
- nginx配置访问本地静态资源
下面说说如何在windows下使用nginx作为静态资源服务器, 1.修改config目录下,这个配置文件,基本上所有的配置都在这里面做, 2.主要的配置参数如下,一些无关的参数我直接去掉了,注意,里 ...
- linux服务器上如何使用nginx访问本地静态资源
查看80端口是否被占用,一般80端口多被apache服务占用. netstat -anp|grep 80 2.修改apache服务的端口号 vim /etc/apache2/ports.conf 3. ...
- URL资源跨域访问 跨域使用session信息
SilverLight 出于对安全性的考虑默认情况下对URL的访问进行了严格的限制,只允许访问同一子域下的URL资源. 下表列出了Silverlight 2.0 中 URL 访问规则: WebCl ...
- Nginx解决前端访问资源跨域问题
被前端跨域问题折磨快2天后,终于用ngnx的方式解决了,所以在此总结下. 该篇只探讨如何用Ngnx解决跨域问题,对于原理不作讨论. 1.首先介绍Windows环境下Nignx的相关命令操作 nginx ...
- nodejs服务实现反向代理,解决本地开发接口请求跨域问题
前后端分离项目需要解决第一个问题就是,前端本地开发时如何解决通过ajax请求产生的跨域的问题.一般的做法是通过本地配置nginx反向代理进行处理的,除此之外,还可以通过nodejs来进行代理接口.当然 ...
- html文件引用本地js文件出现跨域问题的解决方案
在本地做个小demo,很简单,一个html文件,一个js文件,在html文件中通过<script>标签引入js,但是出现了一个意想不到的问题:浏览器报错—— 一番折腾后,终于弄明白了:加载 ...
随机推荐
- logging模块简介python
1 logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同 ...
- Kafka 的分片和副本机制
我们在使用 Kafka 生产和消费消息的时候,肯定是希望能够将数据均匀地分配到所有服务器上.比如在日志收集场景,数据量是非常巨大的,例如大批量的集群每分钟产生的日志都能以 GB 计,所以如何将这么大的 ...
- 力扣479(java)-最大回文数乘积(困难)
题目: 给定一个整数 n ,返回 可表示为两个 n 位整数乘积的 最大回文整数 .因为答案可能非常大,所以返回它对 1337 取余 . 示例 1: 输入:n = 2输出:987解释:99 x 91 = ...
- 阿里云服务网格 ASM 正式发布商业化版本
简介:为了更好地满足企业日益加深的大规模使用服务网格产品.服务多语言互通.服务精细治理等需求,2022 年 4 月 1 日起,阿里云服务网格产品 ASM 正式发布商业化版本,为企业在生产环境下大规模 ...
- [GPT] 同为 nodejs 库的 Puppeteer 和 cheerio 的区别是什么
Puppeteer 和 cheerio 是两个完全不同的库,用途和功能也截然不同. Puppeteer 是一个 Node.js 库,它使用 Chrome 或 Chromium 浏览器作为渲染引擎,通过 ...
- dotnet 读 WPF 源代码笔记 为什么自定义的 UserControl 用户控件不能跨程序集继承
从设计上,用户控件 UserControl 就不是一个合适用来多次继承的类型,更不要说进行跨程序集继承自定义的 UserControl 用户控件.对于大部分的用户控件来说,都是采用组合现有的控件来实现 ...
- vue+vant+js实现购物车原理小demo(基础版)
电商毕业设计里的一个购物车demo,拿vue+vant需要写的核心计算代码只有12行.效果图: main.js: Vue.use(Stepper); .vue文件 <template> & ...
- Codeforces Round 917 (Div. 2)
A. Least Product 存在 \(a[i] = 0\),\(min = 0\),不需要任何操作. 负数个数为偶数(包括0),\(min = 0\),把任意一个改为 \(0\). 负数个数为奇 ...
- Linux上OcenBase单机版部署及基本信息查询
OceanBase单机版部署可以通过在线和离线两种方式部署.在线部署可以通过yum源或者apt源部署,直接拉取官方源码即可.实际使用中,大部分环境连不了外网,本文介绍离线方式安装. 下载"O ...
- Threading Programming Guide:One
苹果支持的产生线程的方式 Operation Object 使用OperationQueue,具体可以参考:Concurrency Programming Guide GCD 使用诸如dispatch ...