使用 Blazor 为土炮云增加 Web 界面,定制歌单已可用
作者:V君 发布于:2022-10-29 14:05 Saturday 分类:我的应用
TL;DR for 立即想拿来用的人:[ 下载 | 源代码 ]
用法: 下载 FNZCM.ConHost.7z 解压得到一个 EXE 和 JSON 配置文件,然后把 wwwroot.zip 下载放到解压出来的两个文件边上,双击 EXE 看看有没有错误, 其余用法参见首发的土炮云[ 别再忍受网抑云欺压了,用起外网IP来搭建自己的私有云音乐吧 ]。
这次的界面调整了专辑(❌Disc)列表布局,做了个卡片列表,还做了个按标题搜索(其实搜索还可以再做细一些),最后就是歌单管理功能了,做了勉强能用的上下移动顺序调整按钮,谁让网页拖动实现这么难呢 °皿°
简单扯一扯缘起
上一次发布的土炮云内置 Web 界面只能使用固定的 m3u 歌单,不爽,那就加个接口吐出元数据集,然后用 Blazor 写个界面,配合 Blob 实现导出定制歌单。
这两次发布时间间隔有亿点长,主要原因有俩,对 Blazor 还比较生疏,外加一直有零碎修改,迟迟没有让自己满意,认为拿出来丢人。又到月底了,得刷存在感,那就告一段落发出来吧
简单扯一扯开发感想
首先点名致谢 KeudellCoding 的 Select2 封装项目,参考这个项目受益匪浅,让我有参照地把需要的 Bootstrap 组件封装起来。(后来用不上了依旧下代码做纪念❌)
针对解析大型(?) JSON 时,界面冻结的问题从爆栈上找到个流式读取的方法,期间定时松绑(?)一下脚本,这样界面就不卡死了。
起初还用了前端路由,发现这东西太难驾驭,后来就索性不动 URL 了,把控件状态写进 localStorage 里,页面载入的时候还原,这也还凑合吧。
最后我来帮懒得吐槽的家伙吐槽一下我还在用老掉牙的 HttpListener ,前端都先进到在浏览器跑 C♯ 了,而后端虽然用了 Core 但还在用上古时期的方式。我只能说这就是习惯了吧,实际上改成 Core 的 Host 方式看起来也问题不大,甚至还能兼容 IIS 呢。
最后我只能说:别想这么多。这只是个玩具项目,首先要能满足自己,其次如果能给有需要的人帮上忙,我就偷着乐了。
标签: 软件开发 C# HTTP Web技术 前端工程 .NetCore
使用 Web API 下载 PDF 遇到的坑
作者:V君 发布于:2022-4-28 20:13 Thursday 分类:挖坑经验
TL;DR:
- 将 XHR 的 responseType 设置为 "arraybuffer"
- 如果使用 axios 则要在参数对象加 responseType:'arraybuffer'
- 获取响应之后用 response 创建 Blob 然后交给 ObjectURL(别忘记type)
- 将创建好的 ObjectURL 交给 IFrame 直接呈现,或者交给 A 标签实现下载
听我扯扯:
前后端分离的项目中遇到需要预览(下载)PDF 的需求,而且用了基于请求头而非 Cookie 的验证方式,因此无法走 IFrame 直接把 API 的 URL 送进去。绕了一圈远路尝试解决验证问题,无果。
回过头想起可以让 XHR 下二进制数据的做法,咕狗“XHR PDF”找到爆栈上面的《XMLHttpRequest to open PDF in browser》。(其实这时候已经看到有回答在 XHR 指定 type 为 'arraybuffer' 了)然鹅把 BLOB 链接放进 IFrame 之后,文字和图片全都不见了,只剩下几页空白页(页数正确)。已经确认过后端输出的 PDF 正常,而通过 A 标签的 HRef 放入 BLOB 连接下载的文件大小跟服务器响应的不一样,体积大约翻了一倍。
在浏览器调试脚本发现 XHR 的 reponse 是字符串,在控制台用 typeof 确认过眼神,这时候只能去咕狗了,“xhr binary data”,第一条返回 MDN 上的《发送和接收二进制数据 - Web API 接口参考》,里面提到了 XHR 的 responseType 属性,设置成 "arraybuffer" 才能避免浏览器把输出内容错误地当成文本来解析。
至此问题完美解决,可喜可贺!这个月差点找不到值得发表的内容 _(:з)∠)_
标签: javascript Web技术 前端工程
在 Blazor WebAssembly 中使用 Ace 代码编辑器
作者:V君 发布于:2021-8-1 15:02 Sunday 分类:折腾手记
TL;DR for 急着想要知道怎么用的人
用爽了和不爽都可以回来听我扯扯
最近开始摸 Blazor 的 WebAssembly 前端项目,尽管早就知道有 WebAssembly 的纯前端版本,但那时候似乎还不太稳定的样子,那就等等再用,保持关注,然后最近就发现它似乎已经可以用了。想拿来试试手又不想太 HelloWorld 就得找点事情做,比如博客管理界面啥的。(终于不咕了么)
其实在 Blazor WebAssembly 之前我就一直都盘算着用 Markdown 来撰写文章了,用 Ace 代码编辑器,然后节流发回后端用 Markdig 渲染了再丢回前端呈现预览,现在可好,用 WebAssembly 方式可以把「原生」.NET 库在浏览器运行了,再有就是 Blazor 的组件化以及前端路由,看起来已经能摆脱 js 和 vue 的束缚,当然目前调用 js 库还是得自己写一点胶水代码,将来生态丰富了就不需要自己胶了吧。
那就先从移植组件开始,参考了 Lucky Seven 的如何优雅的移植 JavaScript 组件到 Blazor,一边对着 Ace 的文档引入目前所需的 API。
起初在 index.html 引入 cdn 脚本,后来发现可以用 import 关键字在脚本文件里引入外部脚本,只是要补充一下库基址。于是就搞起了模块化胶水(JS、Interop、C♯)。使用起来没发现明显的问题,至于性能嘛,前端工程是跑在每个浏览器的,只要不是反应卡顿,都可以忽略掉(❌),可以不太在意性能,把代码写的好看点,这有啥毛病呀(
不扯了,来点类似下集预告之类的吧。整合了 Ace 代码编辑器之后,当然就是搭管理界面的前端工程。找到了个简单易懂的栗子,原来前端路由拦截这么简单。好了打住,欲知后事如何,且听下回分解w
前端新手历险记之在VUE项目中使用Ace编辑器(brace)和一些TypeScript知识点
作者:V君 发布于:2018-9-8 23:52 Saturday 分类:折腾手记
TL;DR
▉ 将Ace编辑器引入项目
1) $npm install brace
2) $npm install --save @types/ace
3) ts:import * as ace from 'brace';
4) ts:import 'brace/...";
▉ TypeScript类型转换,对于 var dom = this.$refs["editor-dom"] 有两种方式
1) ts:ace.edit(dom as HTMLElement);
2) ts:ace.edit(<HTMLElement>dom);//这种方式会使tsx编译器报错标签未关闭,但实际能用
▉ 在TypeScript类中声明可空属性
在标识符后面加感叹号否则必须在构造时初始化,例子:
ts:private editor!: ace.Editor;
虽然这次的收获不多,但还是花了不少时间查资料来弄懂,得好好扯一扯:
在 vue-cli 3.x 创建的项目中启用反向代理
作者:V君 发布于:2018-8-26 21:50 Sunday 分类:折腾手记
TL;DR
1)在项目根目录创建 vue.config.js
2)在文件中指定配置 module.exports -> devServer -> proxy
3)按需增加详细参数 如重写
这次能扯的东西并不多。
主要把时间浪费在咕狗上。什么都不了解就直接搜“vue-cli 反向代理”
粗心大意地忘了加上版本号,首先找到的是在config文件夹创建index.js的方法,没起作用。
后来加上版本号去搜索就发现了vue.config.js,再作为关键字就搜索到了官方文档。
从目录一眼扫下来就发现了遍地文章提到的devServer配置节。
顺便贴一下本次练习中生效的作为参考:
module.exports = { devServer: { port: 8084, proxy: { '/api': { target: 'http://localhost:7808/', changeOrigin: true, pathRewrite: { '^/api': '' }, } } } }
服务端路由为 /md 在前端配置成 /api/md。
或许把前后端路径一致然后去掉pathRewrite参数比较好。
blogger
Google Web Translator
热门日志
随机日志
最新日志
最新评论
- V君
@Quartz:(出现)... - Quartz
怎么不见人了呢... - V君
@Soar:DHCP 协议相... - V君
@Soar:当然是非... - Soar
@V君:谢谢 有空... - Soar
搞一个 1230v3+B85... - V君
@Soar:另外,也可... - V君
@Soar:iscsi服务端... - Soar
难怪这么卡,尤其... - Soar
clone了源码,提示...
分类
存档
- 2024年5月(1)
- 2023年7月(1)
- 2023年5月(1)
- 2022年11月(1)
- 2022年10月(1)
- 2022年9月(1)
- 2022年8月(1)
- 2022年7月(1)
- 2022年6月(1)
- 2022年5月(2)
- 2022年4月(1)
- 2022年3月(1)
- 2022年2月(1)
- 2022年1月(1)
- 2021年12月(1)
- 2021年11月(1)
- 2021年10月(1)
- 2021年9月(1)
- 2021年8月(1)
- 2021年7月(1)
- 2021年6月(1)
- 2021年5月(1)
- 2021年4月(1)
- 2021年3月(1)
- 2021年2月(1)
- 2021年1月(1)
- 2020年12月(1)
- 2020年11月(1)
- 2020年10月(2)
- 2020年9月(1)
- 2020年8月(1)
- 2020年7月(1)
- 2020年6月(1)
- 2020年5月(1)
- 2020年4月(2)
- 2020年3月(3)
- 2020年2月(1)
- 2020年1月(1)
- 2019年12月(1)
- 2019年11月(1)
- 2019年10月(1)
- 2019年9月(1)
- 2019年8月(2)
- 2019年7月(1)
- 2019年6月(1)
- 2019年5月(1)
- 2019年4月(1)
- 2019年3月(1)
- 2019年2月(1)
- 2019年1月(2)
- 2018年12月(2)
- 2018年11月(1)
- 2018年10月(3)
- 2018年9月(4)
- 2018年8月(6)
- 2018年7月(4)
- 2018年6月(1)
- 2018年5月(2)
- 2018年4月(2)
- 2018年3月(3)
- 2018年2月(1)
- 2018年1月(1)
- 2017年12月(1)
- 2017年10月(2)
- 2017年9月(1)
- 2017年8月(2)
- 2017年7月(1)
- 2017年6月(5)
- 2017年5月(2)
- 2017年4月(2)
- 2017年3月(3)
- 2017年2月(2)
- 2017年1月(2)
- 2016年12月(3)
- 2016年11月(2)
- 2016年10月(3)
- 2016年9月(4)
- 2016年8月(2)
- 2016年7月(4)
- 2016年6月(3)
- 2016年5月(1)
- 2016年4月(4)
- 2016年3月(3)
- 2016年2月(1)
- 2016年1月(5)
- 2015年12月(4)
- 2015年11月(5)
- 2015年10月(1)
- 2015年9月(6)
- 2015年8月(4)
- 2015年7月(1)
- 2015年6月(6)
- 2015年5月(3)
- 2015年4月(3)
- 2015年3月(2)
- 2015年2月(1)
- 2015年1月(3)
- 2014年12月(1)
- 2014年11月(1)
- 2014年10月(1)
- 2014年9月(3)
- 2014年8月(1)
- 2014年7月(1)
- 2014年6月(1)
- 2014年5月(3)
- 2014年4月(1)
- 2014年3月(1)
- 2014年2月(2)
- 2014年1月(1)
- 2013年12月(2)
- 2013年11月(2)
- 2013年10月(1)
- 2013年9月(3)
- 2013年8月(14)
- 2013年7月(7)
- 2013年4月(1)
- 2013年3月(4)
- 2013年2月(6)
- 2013年1月(6)
- 2012年12月(8)
- 2012年11月(6)