-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
目的
在ZCMS中的文章编辑器是UEditor,我曾经在写了一个UEditor插件叫uploadLocalImage,作用是自动上传粘贴到文章编辑器中的本地图片到服务器。在从word文档中copy内容到编辑器中就可以自动上传其中的图片了。
在之前的笔记 #16 中有记录,在chrome插件中是通过NPAPI调用本地dll文件去读取本地文件,chrome45及以后的版本,加强了安全限制,禁止了NPAPI,所以chrome插件不能再访问本地文件了。
现在的思路是要求客户安装一个可执行程序,这个程序在本地启一个httpserver,编辑器中用js通过ajax和本地的httpserver通讯,通知这个本地服务上传本地硬盘上的文件到cms后台去。从而解决js不能访问本地文件的限制。而且这种方式与浏览器无关,不用为不同的浏览器开发插件了。
实现过程
- 在github上搜索“http server”在c#语言里找项目,发现项目的代码量都比较多
- 进.net的官网看看,https://www.asp.net/get-started
在asp.net的官网发现asp .net core的入门特别简单,并且明显是用到了webserver的,于是安装.net core sdk,并试运行一个示例,成功 - 查看示例源码,关键的一个组件是,实例化一个
WebHostBuilder - 在百度搜索
WebHostBuilder,发现这篇文章,http://www.cnblogs.com/artech/p/net-core-hello-world.html 文中附有源码,将源码下下来,运行之 - 第5个示例运行有误,开始认为是配置文件的版本不匹配,反复尝试,调整配置,花了两个小时,终于发现问题在于index.cshtml里head标签没有正常结束
期间还在github上找了一个简单示例,并根据这个示例尝试调整配置
https://github.com/SunKD/practice-portfolio/blob/master/Program.cs - 至此,在asp .net core里创建一个web服务器的过程基本了解。
- 接下来是接受跨域的http请求
- 在github搜索 "IApplicationBuilder app.UseMvc Access-Control-Allow-Origin" (事后发现应该先在百度搜索“.net core 跨域”,能更快速地定位到一个示例”https://www.cnblogs.com/qinghub/p/6398345.html “和”https://github.com/ingress2018/asptest/blob/master/src/AspNetCoreDemoApp/Startup.cs“)
- 在众多代码中发现这样的写法
https://github.com/geruchvitaliy/Demo-AspNetCore-ApiEntityFramework/blob/fc22193f74032a5a0bbff04e4989e93cca6a1707/src/Api/Startup.cs
https://github.com/SlingingCode/Healthy/blob/9fc16e7a6b11f10266c755eea0874e25faa6f784/Healthy.API/Startup.cs
services.AddCors (options => options.AddPolicy ("AllowAll", policy => policy.AllowAnyHeader ().AllowAnyMethod ().AllowAnyOrigin ().AllowCredentials ()));经测试可跨域访问
- 百度搜索“Mvc ActionResult” https://www.cnblogs.com/kissdodog/archive/2013/01/07/2850334.html
发现返回json数据的写法
public IActionResult status (string name) {
var jsonObj = new {
version = "1.0.0",
status = "ok",
error = "",
};
return Json (jsonObj);
}或
public object status (string name) {
var jsonObj = new {
version = "1.0.0",
status = "ok",
error = "",
};
return jsonObj;
}- 写了例子,用postman测试成功
- 再测试post请求,用postman测试,有错误“415 Unsupported MediaType”
- 在google里搜索,发现原来要向后台提交数据必须是json格式
https://stackoverflow.com/questions/41597455/net-core-webapi-unable-to-post-data-with-postman-error-415-unsupported-me - 再多次尝试,终于能跨域发出post请求,并得到返回值
- .net core里怎么处理post请求,在github里搜索一下即可,例于
https://github.com/tautvisv/HPTB/blob/master/HolidaysPlanningTool/src/HolidaysPlanningToolWeb/Controllers/ManageController.cs
https://github.com/SlingingCode/Healthy/blob/master/Healthy.API/Controllers/PersonsController.cs - 至此服务端可与js交互了,在neditor.all.js里注释掉wordimage插件,
- 在js控制台直接测试跨域提交post请求,js代码如下
$.ajax({
url: 'http://localhost:10808/localupload',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
"action":"localupload",
"param1":"file:///C:\\Users\\abeet\\AppData\\Local\\Temp\\ksohtml\\wps58D8.tmp.jpg",
"sendUrl":"http://localhost/api/catalogresources/9191/frontupload?siteID=14",
"localSize":1024,
"localExt":"gif,jpg,bmp,svg,png",
"cookie":"IPCity=%E6%9C%AA%E7%9F%A5; ASPSESSIONIDQQARATRD=AEHBAMACAEIMHEHGPOGLDGEO"
})
}).then(function(res){
console.log(res)
},function(res){
console.error(res)
})- 引入自己的zuploadlocalimage插件,并调整逻辑,先将本地图片都换成一张固定的图片,成功
- 接下来是要查找 .net core里http客户端相关的实例
- github上找到这样一个类 https://github.com/justeat/httpclient-interception/blob/master/src/HttpClientInterception/HttpRequestInterceptionBuilder.cs
感觉太复杂,.net core里应该会有提供更简单的方法。 - 查 .netcore的api手册,没有找到与http通讯有关的内容,在microsofe全站搜索“HttpWebRequest”找到了 https://docs.microsoft.com/zh-cn/dotnet/api/system.net.httpwebrequest?view=netframework-4.7.2
看来.net core里没有HttpWebRequest,.net framework里有 HttpWebRequest。
怎么办?
先试试google一下“asp.net core HttpWebRequest”
找了一篇文章 https://zhuanlan.zhihu.com/p/22764927 ,试试用它这个写法
看来只能用 WebRequest了,
参考一下
https://github.com/qinyuanpei/HttpServer/blob/master/HTTPServer/HTTPClient/Program.cs
的写法试试,向远程服务器请求内容成功。
接下来需要发送文件了。 - 在github里搜索“WebRequest Method POST GetRequestStream Write multipart/form-data File”
找到一些参考如
https://github.com/xiongc169/20160331-Hs.web/blob/master/hs.web/hs.console/utility/upload/UploadUtility2.cs - 依照这个写各服务器发起请求,用PostMan发起一个请求
{
"action":"localupload",
"param1":"file:///C:\\Users\\abeet\\AppData\\Local\\Temp\\ksohtml\\wps7D7A.tmp.jpg",
"sendUrl":"http://localhost/api/catalogresources/9191/frontupload?siteID=14",
"localSize":1024,
"localExt":"gif,jpg,bmp,svg,png",
"cookie":"IPCity=%E6%9C%AA%E7%9F%A5; ASPSESSIONIDQQARATRD=AEHBAMACAEIMHEHGPOGLDGEO"
}结果有错误,在java类里打断点跟踪后发现,其一要传递siteID和addUser,其二我们后台java方法限定了表单元素的name为file,调整后,顺利地通过c#上传了临时文件夹下的图片。
- 至此终于可以在cms后台的编辑器里正式测试了。
- 在js里对预览路径进行处理后就ok了
- 生成exe文件,在项目根目录执行
dotnet build -r win10-x64 - 然后是要注册为服务,在百度里搜索“C# 注册为windows服务”找到的文章有
https://www.cnblogs.com/sorex/archive/2012/05/16/2502001.html
需要特别的写法,还需要使用installutil.exe 去安装,这个安装文件客户的机器上未必会有 - 在github里搜索 “windows service”,发现有一个项目的星比较多
https://github.com/kohsuke/winsw
winsw 可以将Windows上的任何一个程序注册为服务 - 下载winsw,并装备好配置文件,然后将winsw,zvingtools.exe及所有依赖,一起打包为自解压程序,解压到program files目录,并执行
winsw uninstall
winsw install
winsw start- 试执行这个自解压程序,在没有使用管理员身份运行的情况下,服务也启动起来了。
使用PostMan尝试连接 http://localhost:10808/ 成功! - 耶,到此目标初步达成——用c#实现一个http服务接受ajax请求,c#实现http客户端上传文件到远程服务器
Metadata
Metadata
Assignees
Labels
No labels