通过fetch发送 post 请求下载文件

背景 最近遇到一个下载的需求,由于 url 参数太长(常用的下载方法 a 标签或者 location.href 的方法都是 get 请求,get 请求参数长度有限制),无法下载,考虑了好几种方案,最终还是觉得通过 ajax 的 POST 方法进行下载,比较容易实现,下面记录实现过程以及遇到的问题。 但是由于 AJAX 并不会唤起浏览器的下载窗口,AJAX设计的初衷就是用来实现异步刷新的,用以改善原始的 form 表单提交刷新页面的问题,那么如何来解决呢? POST 方法下载实现原理 通过 fetch 请求获取文件,然后利用 Blob 对象来接收处理,在接收到后端返回的文件后,把其转化一下,放入a标签的href中,并触发下载行为。 实现的代码如下: fetch(url, { method: 'POST', body: JSON.stringify(params), header: { 'Content-Type': 'application/json;charset=UTF-8' } }).then(function(response) { return response.blob(); }).then(function(blob) { const link = document.createElement('a') link.style.display = 'none' link.href = URL.createObjectURL(blob) document.body.appendChild(link) link.click() // 释放的 URL 对象以及移除 a 标签 URL.revokeObjectURL(link.href) document.body.removeChild(link) }); 这里需要注意的是要记得要调用 response 的 blob 方法,这样才会返回一个 blob,如果你没用过 blob 的话,可能你以前只知道 json 和 text,其实 response 的 body 还可以转化为 arrayBuffer 和 formData。...

November 22, 2019 · 2 min · 306 words · 桃翁

如何对 React 函数式组件进行优化

前言 目的 本文只介绍函数式组件特有的性能优化方式,类组件和函数式组件都有的不介绍,比如 key 的使用。另外本文不详细的介绍 API 的使用,后面也许会写,其实想用好 hooks 还是蛮难的。 面向读者 有过 React 函数式组件的实践,并且对 hooks 有过实践,对 useState、useCallback、useMemo API 至少看过文档,如果你有过对类组件的性能优化经历,那么这篇文章会让你有种熟悉的感觉。 React 性能优化思路 我觉得React 性能优化的理念的主要方向就是这两个: 减少重新 render 的次数。因为在 React 里最重(花时间最长)的一块就是 reconction(简单的可以理解为 diff),如果不 render,就不会 reconction。 减少计算的量。主要是减少重复计算,对于函数式组件来说,每次 render 都会重新从头开始执行函数调用。 在使用类组件的时候,使用的 React 优化 API 主要是:shouldComponentUpdate 和 PureComponent,这两个 API 所提供的解决思路都是为了减少重新 render 的次数,主要是减少父组件更新而子组件也更新的情况,虽然也可以在 state 更新的时候阻止当前组件渲染,如果要这么做的话,证明你这个属性不适合作为 state,而应该作为静态属性或者放在 class 外面作为一个简单的变量 。 但是在函数式组件里面没有声明周期也没有类,那如何来做性能优化呢? React.memo 首先要介绍的就是 React.memo,这个 API 可以说是对标类组件里面的 PureComponent,这是可以减少重新 render 的次数的。 可能产生性能问题的例子 举个例子,首先我们看两段代码: 在根目录有一个 index.js,代码如下,实现的东西大概就是:上面一个 title,中间一个 button(点击 button 修改 title),下面一个木偶组件,传递一个 name 进去。...

November 19, 2019 · 4 min · 774 words · 桃翁

在mac上安装XAMPP并搭建 typecho 博客

在 v 站上看一个自己非常喜欢的博客主题:阿星Plus,但是由于是用 .Net 写的,自己完全不熟悉 .Net,所以就准备自己按照他的博客风格写一份 typecho的主题。 我也没接触过 PHP,在安装环境这一步就把我难住了,历经磨难,最终选择了 XAMPP 来搭建 PHP 环境,在这里记下搭建的过程和遇到的坑。 我刚开始去搜索 「XAMPP 搭建 typecho」,然而由于 typecho 资料太少,根本搜不到,所以选择了搜索「XAMPP 搭建 wordpress」,然后才一步一步的安装好了 XAMPP。 什么是 XAMPP XAMPP(Apache+MySQL+PHP+PERL)是一个功能强大的建站集成软件包。 安装 XAMPP 首先要知道 XAMPP 有两中安装方式: 第一种:OS X的XAMPP是OS X的本地安装程序。它将Apache,PHP和其他XAMPP组件直接安装在OS X系统的 /Applications/XAMPP 文件夹中。 第二种:XAMPP-VM是OS X的虚拟机,它包括Apache,PHP和其他XAMPP组件,并在OS X系统上的基于Linux的虚拟机中运行它们。 这两种方式我都试过,相信我,采用第一种安装方式。 值得提醒的是在 XMAPP 首页下载的是 OS X 的虚拟机的,下载的时候文件名称会有 vm ,要下载安装程序的,要去 Download 里面下载,文件名称会有 installer 的字样。 使用 XAMPP 这里我写的会比较简单,自己随便看看就知道怎么用了。 安装好了进入界面,直接点 Start All就行,如果上图中花框的灯是像我图中的绿色就代表启动成功,失败了就会是红色。 安装 typecho 将官网下载的 typecho 安装包下载下来。 将安装包移动到 htdocs 文件夹下并解压,htdocs 文件夹路径如图,在应用程序 -> XAMPP->htdocs 访问 localhost/build 即可进入安装页面进行 typecho 的安装。 遇到的问题 1....

November 14, 2019 · 1 min · 107 words · 桃翁

如果解决虚度时光,首先做到要事第一

阅读文章之前你可以花半分钟想想你觉得你自己最虚度的时光是时候? 夸自己 可能在很多人的眼里,我以及算是一个努力、上进的人了,那是因为他们只看到了我努力的时候,没有看到我虚度的时候。 一般在工作日我还是非常的恪守自己的原则,在不上班的时候都会提升自己,比如看书、听课、阅读、写作等方式。跟一般的人比起来更努力的点就是早上我会先学习一个小时,我一般 7 点半就会起床,然后看书或者听课一小时后,也就是 8 点半的时候才会去洗漱,下班回来也很少除了和女朋友每天至少视频半小时外,其余时间用得都很充分(用的方向对不对先不谈)。 虚度 接下来就说到重点了,虚度的时光。 我觉得我最虚度的时光就是周末,本来会有充足的时间来学习,但是当打开电脑突然不知道应该干什么(这个时候非常的难受,经常在这个时候想做人的意义是什么),然后就去看书,看了一会儿还是会觉得无聊,然后就说打会儿游戏吧,我一般有个习惯就是一直会打到输才会停止,往往经常又是连赢好几把,导致有可能一打就是一上午或者一下午过去了,然后就去做饭吃。 一旦到晚上七八点的时候,那个时候突然又觉得学习的奋劲儿又来了,然后会认真看书,看课程写文章等自己觉得对的事儿。然后就开始感叹自己白天的时间又浪费了,晚上再来补,那我们重庆人的话来说就是:「早不忙,夜慌张」。 为什么 很好奇的是为什么工作了才会出现这种情况,而在高中大学没有出现。 在高中的时候,我们大家的目标非常明确,就是考大学,每天要做的事情就是看书,做题就行,目的很明确,要做的事情非常的清晰,所以不会有这种不知道该干啥的情况。 到大学的时候我长期呆在实验室,每天 11 点才到寝室,然后觉得自己应该放松了,就玩玩手机,聊聊天是应该的,这在我的大脑里是应该做的,到了周末的时候,我也觉得应该放松,所以在放假之前已经给自己订好了周末要做的事情,会出去玩,或者打游戏等。 我觉得我就是没做好《高效能人士的七个习惯》里的要事第一。 有兴趣的话我也可以写写这本书的读后感,这本书是今年我读的书里收益最大的书。 相信要事第一还是不难理解,就是把最重要的事情先做。所以首先我应该找出对我来说最重要的事情,然后我没找出来,或者说我没去认真思考对于我来说最重要的事情是什么,导致我有空闲的时候不知道应该干什么,因为想干的事情太多,导致觉得都不重要,你想想你会不会有过这样的感受。 我再说一种情况,我觉得大部分人也有过这种经历,在工作日的时候想做的事情很多,然后把原因归结为上班太忙,所以在工作日不做,准备打算到周末去做,然而到周末了,往往又由于想做的事情太多,导致最后不做了。 然后我回想我工作以前为什么没有这种状态,感觉每天都知道自己应该干啥,就算是打游戏也知道自己该打游戏了。 如何解决 这些都是没有做到要事第一的第一步,找出最重要的事情。 那么如何找到最重要的事情呢,我觉得一个很好的方法就是「做减法」。做加法谁都会做,想到什么事情就忘自己的待办事项或者大脑里面加就行了,但是这样就会导致要做的事情越来越多,最后太多了,然后都不做了。 如果做减法我觉得可以用《搞定》书中的 GTD 方法来帮助我们完成,相信很多人对 GTD 的印象只是存在于写 Todo List,然后把做完的事情标记为完成。其实这只是其中的一个小步骤,GTD 最核心的思想是想通过工具把事情从我们的大脑里面清空,让我们的大脑能专注做一件事情,而不是在做某件事情的时候,又想到其他事情没做,这样就会分心,效率就会大大的降低。 GTD 会有五个核心步骤:收集、处理、组织、检查、做。其中收集的作用就是把你的想法从大脑清空,通过工具帮你把想法记下来,处理过程就是我们做减法的过程,将一些不重要的东西给丢掉。 如果有兴趣,GTD 后面我专门写一篇文章来介绍,非常有效的一种习惯。 丢掉之后还有一些你需要的做的事情,然后再把这些需要做的事情再去认真思考什么事情是最重要的,然后再去做。 总结 文章写了为什么会有虚度的感觉,然后为什么会产生虚度的感觉,然后结合 GTD 给出了解决方案,希望能给你带来启发。 希望你在留言区里留出你什么时候会最感觉自己虚度了,然后又是怎么去解决的呢?

November 7, 2019 · 1 min · 44 words · 桃翁

如何让 useEffect 只在依赖变化的时候执行

遇到问题 今天遇到一个 useEffect 的问题,遇到一个问题:在 useEffect 里面发异步请求,然后第二个参数的依赖也是异步请求之后得到的结果,然后就导致最终结果会请求两次 useEffect 里的函数。 const [metaKey, setMetaKey] = useState<string[]>([]) // useEffect1 useEffect(() => { getServiceCoreIndexParam().then((res: IResult) => { setMetaKey(res.data.defaultValue) return res.data }) }, []) // useEffect2 useEffect(() => { getAdvisorIndexTable({ visitdate: props.visitdate, advisorSupervisor: props.advisorSupervisor, comparevisitdate: props.comparevisitdate, metaKeys: metaKey || [] }).then((res: IResult) => { res.success && setTable(res.data) }) }, [props.visitdate, props.advisorSupervisor, metaKey, props.comparevisitdate]) 分析一下这段代码,首先在组件 mount 的时候,useEffect2 会调用一次 getAdvisorIndexTable,当 useEffect1 执行完毕之后 setMetaKey 后,由于 metaKey 发生改变,导致 getAdvisorIndexTable 还会调用一次,这很明显是我们不想看到的结果,因为这只是一个默认请求,然而发了两次请求。...

October 14, 2019 · 2 min · 266 words · 桃翁