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,但是出现了一个意想不到的问题:浏览器报错—— 一番折腾后,终于弄明白了:加载 ...
随机推荐
- background-blend-mode
由于 mix-blend-mode 这个属性的强大,很多应用场景和动效的制作不断完善和被发掘出来,遂另起一文继续介绍一些使用 mix-blend-mode 制作的酷炫动画. CSS3 新增了一个很有意 ...
- CSS 样式清单整理(二)
16.元素占满整个屏幕 heigth如果使用100%,会根据父级的高度来决定,所以使用100vh单位. .dom{ width:100%; height:100vh; } 17.CSS实现文本两端对齐 ...
- 【笔记】Oracle列转行unpivot&行转列 PIVOT
unpivot 说明:将表中多个列缩减为一个聚合列(多列转多行) 语法:unpivot(新列名 for 聚合列名 in (对应的列名1-列名n )) 写到了一个力扣的题,发现这个unpivot函数还没 ...
- 力扣238(java)-除自身以外数组的乘积(中等)
题目: 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 . 题目数据 保证 数组 nums之中任意元素的全 ...
- PolarDB助力易仓打造跨境行业生态链协同的产业链SaaS
简介: 2022年7月,易仓ECCANG WMS东南亚版正式上线!经过9年快速发展,易仓已经成为一家跨境全生态综合服务商,也见证了跨境行业从起步到万亿级的增长.而PolarDB作为面向下一代云原生关系 ...
- 比心云平台基于阿里云容器服务 ACK 的弹性架构实践
简介:本文主要探讨比心云平台如何利用阿里云容器服务 ACK,来构建应用弹性架构,进一步优化计算成本. 作者:韩韬|比心技术 前言 应用容器化改造后,不可避免地会面临这样一个问题:Kubernetes ...
- Java 定时任务技术趋势
简介:定时任务是每个业务常见的需求,比如每分钟扫描超时支付的订单,每小时清理一次数据库历史数据,每天统计前一天的数据并生成报表等等. 作者:黄晓萌(学仁) Java 中自带的解决方案 使用 Time ...
- 阿里云云效技术专家:一文详解kubernetes下5种常见发布模式如何选择
简介: Kubernetes下5场场景应用发布方式的选择,每种发布模式适合什么样的场景,以及如何在阿里云云效上高效落地. 作者:郑云龙,阿里云云效技术专家 Kubernetes面向通用场景提供了非常灵 ...
- [Unreal] 虚拟现实理论与最佳实践
优秀的虚拟现实场景所需要具备的特点: 真实感.沉浸感.舒适性.流畅性. VR的这些特点上有其它媒体所不具备的优势,主要通过硬件来实现. VR 的沉浸感让用户置身于周围世界,也引发了一些独特的症状: 眼 ...
- [PHP] Laravel 依赖注入使用不当引起的内存溢出
业务逻辑: 正常在 controller 方法的参数中注入某个类,方法中使用这个类时发生内存超出提示. 分析: 过往显示,正常使用依赖注入是不存在问题的,那么很有可能是哪里发生了循环引用,导致一直请求 ...