如何在 Formidable (Node.js) 中取消用户上传?

2024-04-14

我已经研究这个问题两天了,但我被困住了。我正在使用 Node.js 和 Express,并且正在尝试实现上传表单。基本上,我希望表单执行以下操作:

  • 检查文件的大小,如果太大则取消上传(当我说取消时,我的意思是防止任何进一步的数据写入磁盘并删除临时文件)

  • 检查文件类型并确认它是正确的类型(.jpg、.png 等),如果不是,则停止进一步写入磁盘并删除临时文件。

目前,我正在上传工作,当文件太大或与正确的类型不匹配时,我会发出错误,然后使用以下命令删除该文件fs.unlink()整个文件写入磁盘后。但我发现这种方法存在一个潜在的问题:如果用户上传一个巨大的文件(GB 大小)怎么办?按照我现在的方法,它最终会从我的机器上删除,但不会浪费大量资源。所以基本上,我希望使用最少量的资源来确认文件可以上传。这是我到目前为止的代码:

    var path = absolutePath + '/public/images/users/' + req.session.userId + '/';
    var maxSize = 3146000; // 3MB
    var form = new formidable.IncomingForm();
    form.uploadDir = path;
    form.keepExtensions = true;

    form.on('error', function(message) {
        if(message)
        {
            res.json({err: message});
        }
        else
        {
            res.json({err: 'Upload error, please try again'});
        }
    });

    form.on('fileBegin', function(name, file){
        if(form.bytesExpected > maxSize)
        {
            this.emit('error', 'Size must not be over 3MB');
        }
    });

    form.on('file', function(name, file) {
        var type = file.type;
        type = type.split('/');
        type = type[1];

        if(type != 'jpeg' && type != 'png' && type != 'gif')
        {
            this.emit('error', "JPG's, PNG's, GIF's only");
            fs.unlink(file.path);
        }
        else
        {
            fs.rename(file.path, path + 'profile.' + type);
        }
    });

    form.on('progress', function(bytesReceived, bytesExpected) {
            console.log(bytesReceived); //This is just to view progress
    });

    form.parse(req);

我也很困惑,因为根据文件https://github.com/felixge/node-formidable https://github.com/felixge/node-formidable, 它说:

遇到错误的请求会自动暂停,如果您希望请求继续触发“数据”事件,则必须手动调用 request.resume()。

这太好了,但我似乎无法让它发挥作用。每当我发出“错误”时,“数据”事件就会不断触发,直到完成。

Attempts

我尝试在发生错误时取消请求,但无济于事。req.pause()没有为我做任何事req.end() and req.abort()给了我一个错误,说它不是一种方法,并且req.connection.destroy() and req.connection.end()刚刚发送了一个 POST 请求循环。

最后的想法

所以我正在寻找的东西似乎应该是常见的,但我花了两天的时间在互联网上搜索彻底的实现,但我似乎找不到任何东西。我的意思是,在整个文件上传后检查文件的大小和类型很简单,但谁愿意浪费所有这些资源呢?更不用说恶意用户可以做的事情了。

我将继续工作,直到我得到我想要的东西,但我认为这个问题可能与其他一些用户相关,希望我能得到一些帮助!

谢谢你的时间。


我将尝试回答我自己的问题......

因此,在对 Formidable 进行了一些尝试和错误之后,我干脆放弃了它并转而使用多方 https://github.com/superjoe30/node-multiparty。当发出巨大错误时,多方实际上会取消上传。

我的解决方案

因此,我的解决方案利用客户端大小和类型检查(代码中未显示)。然后请求被发送到服务器。在服务器上,我在写入磁盘之前再次检查文件大小和类型是否正确。我可以通过使用 Multiparty 来做到这一点part事件。如果它们不正确,那么我只需发送包含 413 错误的响应。 (谢谢josh3736澄清浏览器中应该发生什么。)发回 413 后,浏览器的行为有点零星。对于我正在测试的浏览器,它只显示了pending发布请求。我认为这种行为是由于整个表单尚未处理,因此,它不会接受任何回复。这似乎不是最优雅的处理方式,因为没有显示错误代码,但只有绕过客户端检查的恶意用户才会遇到这种行为(我的网站依赖于 Javascript,因此所有用户都会遇到这种情况)如果他们想使用我的网站,则启用)。这就是我的文字解决方案,现在是一些代码......

app.post('/profile/profile_pic', urlencoded, function (req, res) {

    var path = absolutePath + '/public/images/users/' + req.session.userId + '/';
    var maxSize = 3146000; // 3MB

    var options = {uploadDir: path};
    var form = new multiparty.Form();

    form.on('error', function(message) {
        res.status = 413;
        res.send(413, 'Upload too large');
        res.end();
    });

    form.on('file', function(name, file) {
        var type = file.headers['content-type'];
        type = type.split('/');
        type = type[1];
        fs.rename(file.path, path + 'profile.' + type);
        path = '/images/users/' + req.session.userId + '/profile.' + type;
    });

    form.on('part', function(part) {
        var type = part.headers['content-type'];
        var size = part.byteCount - part.byteOffset;

        if(type != 'image/jpeg' && type != 'image/png' && type != 'image/gif' != 'application/pdf' || size > maxSize)
        {
            this.emit('error');
        }
    });

    form.on('close', function(){
        res.json({err: 0, path: path});
    });

    form.parse(req);

});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Formidable (Node.js) 中取消用户上传? 的相关文章

  • 输入值返回 NaN

    如果有人可以帮助我 因为我不知道为什么控制台中总是有 NaN 一切似乎都很好 该代码应该获取输入值并进行简单的计算 不幸的是 我收到了 NaN 所以我决定使用 console log 来探索值 它向我解释了每个输入的值都是 NaN 我认为这
  • 使用字符串函数查找周期字符串

    我正在寻找一种方法来检查字符串是否是周期性的或不使用 JavaScript 要匹配的示例字符串可以是11223331122333 然而 10101不应该匹配 来自 python 我使用了 RegEx 1 但速度相当慢 有没有任何字符串方法可
  • WebStorm已将目录中的所有文件标记为非项目文件

    WebStorm 已将我的项目子目录 根目录的服务器部分 中的所有文件标记为非项目文件 它发生在我转换到 Babel 然后又转换到 TypeScript 的过程中 我已经删除了 TypeScript 的内容 想知道这是否与该配置有关 我相信
  • Flot 中轴的逗号分隔数字

    有没有办法让 Flot 使轴编号以逗号分隔 例如 用 1 000 000 代替 1000000 您可以通过使用轴的tickFormatter 属性来做到这一点 xaxis tickFormatter function val axis in
  • 如何在 Rollup 中配置从多个输入文件仅生成单个输出文件?

    配置Rollupjs生成库时 如果输入是由多个javascript文件组成的数组 我们如何才能将这些输入生成为一个输出 js 文件呢 export const lgService input src app services livegiv
  • 如何从主体上的 onClick 事件获取鼠标单击的绝对位置?

    我试图获取鼠标单击相对于浏览器 主体的绝对位置 顶部和左侧 not主体内的任何父元素 我有一个绑定到 body 的侦听器 但 e pageX 和 e pageY 为我提供了相对于 div 的位置 请注意 我可以利用 jQuery 和 YUI
  • Extjs中始终显示Slider的提示文本

    在 Extjs 4 1 1a 中 如何保持tip text滑块始终可见 目前 tip text每当用户拖动滑块栏时就可见 我搜索了docs http docs sencha com ext js 4 0 api Ext slider Sin
  • 如何在D3中导入json数据?

    如何在D3中导入json文件 I did d3 json temp json 但是我如何在进一步的代码中访问这个数据集呢 到目前为止我已经尝试过 var data d3 json temp json 但使用 data data 在其余代码中
  • RxJS 将三元组中的属性组合到表中

    我有一项服务生成类似于三元组的对象 它们将采用以下格式 country attribute value Example country usa attribute population value 100 country mexico at
  • 如何将 !important 添加到 CSS-in-JS (JSS) 类属性?

    我正在尝试使用一些 CSS in JS 类这个答案 https stackoverflow com questions 54525334 how can i change the label size of a material ui te
  • JS 检查深层对象属性是否存在[重复]

    这个问题在这里已经有答案了 我正在尝试找到一种优雅的方法来检查对象中是否存在某些深层属性 因此 实际上试图避免对未定义的情况进行巨大的保护性检查 例如 if typeof error undefined typeof error respo
  • 无法读取未定义的属性“messageHandlers”

    我想将 JavaScript 变量传递给 Swift 我在 JavaScript 中遇到错误并进行了搜索 但没有得到任何结果 错误是 类型错误 无法读取未定义的属性 messageHandlers 任何人都可以帮忙吗 我在 Xcode 中的
  • 如何检测鼠标指针位于浏览器关闭按钮上时的事件? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 换句话说 这是用于检测事件的 javascript jquery 代码当鼠标指针位于浏览器的关闭按钮 X按钮 上时 或者当鼠标指针进入
  • (jQuery) 在 cookie 中单击时保存复选框状态

    关于此功能有很多主题 但我似乎无法让它工作 我在谷歌上搜索了这个具体案例 有一堆链接让我来到这里 但奇怪的是我似乎无法让它们工作 我所做的唯一工作如下 http dl dropbox com u 2238080 a old z htm ht
  • Javascript 仅在 Chrome 中打开开发者工具后才起作用

    我和这里有同样的问题 为什么JavaScript只有在IE中打开开发者工具一次后才能工作 https stackoverflow com questions 7742781 why javascript only works after o
  • 在画布中的鼠标位置放大/缩小

    我正在尝试使用 p5 js 实现缩放功能 当前缩放级别以及 x 和 y 位置存储在controls view目的 默认位置或 0 0 位置位于左上角 问题是调整放大 缩小时的 x 和 y 位置值 以便无论视图的当前位置是什么 它都会停留在缩
  • 无法在heroku上推送node.js应用程序

    我尝试在heroku 上推送我的node js 应用程序 但是 无法检测到此应用程序的默认语言 我什至尝试过heroku buildpacks set heroku nodejs 但还是无法推动 Counting objects 31 do
  • 为什么我无法访问多个网络调用的结果?

    在我的 Node 应用程序中 我试图获取包裹的运输数据 我需要一种方法来获取 json 数据并将其附加到对象或其他东西 以便我可以将其传递到我的渲染页面 使用 pug 这是我的代码 var test for var i 0 i lt res
  • JavaScript 有内置的 stringbuilder 类吗?

    I see a few 代码项目解决方案 http www codeproject com KB scripting stringbuilder aspx 但是JavaScript中有常规的实现吗 如果您必须为 Internet Explo
  • Google Universal Analytics - 命令被忽略

    我正在使用 Google Universal Analytics 来跟踪页面浏览量 当我导航到具有 Google Analytics 网站实时功能的页面时 我可以看到 因此我的代码一定可以正常工作 然而 Chrome 一直在控制台中显示 I

随机推荐

  • 如何选择博客模型中的最后一个和倒数第二个条目?

    我有一个模型 blog posts 其中有一个字段 published at 我想从该模型中选择最新的两个博客以显示在我的主页上 但不确定如何构建它 目前 我有一个解决方法 可以获取一部分数据 但当我表中没有任何内容时 它会不断失败 而不是
  • ARM架构中不同处理器模式下如何使用内核堆栈?

    据我了解 每个进程都有一个用户堆栈和内核堆栈 除此之外 ARM 架构中的每种模式都有一个堆栈 所以我想知道不同的堆栈和堆栈指针在 ARM 模式下如何工作 另外 何时会使用与进程关联的内核堆栈 何时会使用与进程关联的内核堆栈 当您进行系统调用
  • Python 中枚举的枚举?

    Python 中是否可以有枚举的枚举 例如 我想要 enumA enumB elementA elementB enumC elementC elementD 供我参考elementA as enumA enumB elementA 或参考
  • 设置 GLEW 窗口?

    我有 Visual Studio 2010 我想在其上设置 glew h 我执行了这一步 但仍然出现链接器错误 1 下载glew包 2 将 h文件复制到C Program Files x86 Microsoft SDKs Windows v
  • Parsley.js - 更改错误容器

    我想改变每个错误消息的位置 即在相应的位置显示错误消息 div class errorBlock div 通过使用文档代码 错误消息显示在元素 输入 之前 而不是按预期显示 有任何想法吗 根据文档 errors container func
  • Knex 连接 Heroku Postgres 时出现错误?

    我正在尝试将 Heroku Postgres 与 Knex 连接 它在本地运行良好 但是当我推 Heroku 时 并尝试注册一个帐户 我收到这个错误 code DEPTH ZERO SELF SIGNED CERT 但我推 Heroku 我
  • Windows 服务错误 1053

    我目前正在编写一个 Windows 服务 它连接到 crm 系统以拉下一个计划 然后运行各种数据源等 我已经一切正常 除了当我安装所有内容并尝试运行启动服务时 我收到以下错误 错误 1053 服务未响应启动或控制请求 及时时尚 这是我在 S
  • 在 JavaScript 中,await 是否可以保证执行顺序而不需要赋值?

    主题 我可以说下面的两段代码是相等的吗 await someFunc no assignment here doSomethingAfterSomeFunc and someFunc then gt doSomethingAfterSome
  • 如何在android http POST中添加参数?

    friends 我正在尝试使用以下教程将文件上传到 php 服务器http getablogger blogspot com 2008 01 android how to post file to php server html http
  • 添加带有多个小部件链接的右键单击上下文菜单?

    我的问题是一种后续行动这个问题 https stackoverflow com questions 12014210 python tkinter app adding a right click context menu 23834156
  • 如何使用标准 MVC Core 依赖注入解析未注册类型

    有没有办法得到IServiceProvider GetService
  • 如何在 matplotlib 中的另一个图上添加一个图?

    我有两个包含数据的文件 datafile1 和 datafile2 第一个始终存在 第二个仅有时存在 因此 datafile2 上的数据图被定义为我的 python 脚本中的函数 geom macro 在 datafile1 上的数据绘制代
  • Visual Studio 忽略 try catch - 仅调试

    我认为错误处理是个好主意 调试时它可能会妨碍 特别是对于用户友好的消息 在 VB6 中 我只需选中编译器的一个框即可忽略我的错误处理 我found https stackoverflow com questions 893277 is th
  • Mediator/EventAggregator 差异

    另外 当我需要在松散耦合的对象之间进行通信时 例如 MVVM的 ViewModel 有关最佳编程实践的不同书籍和博客建议使用 Mediator EventAggregator 模式 我的问题是关于这些模式之间的差异 关系 谁能为我描述一下它
  • 张量流自定义运算梯度

    我们想要在张量流中创建一个自定义层 因此 我们决定简单地从一个玩具示例开始 复制层 经过一番尝试和错误后 我们发现梯度似乎会传递正确的值 然而 在第二次迭代中 特征得到了 NAN 这可能是一个简单的错误 但目前我看不到它 总的来说 我有两个
  • 什么 Java 垃圾收集器清理 PermGen?

    垃圾收集者名单 串行GC 并行气相色谱 并行旧GC 浓缩标记扫描GC G1 GC 我知道当您启用 ClassUnloading JVM 选项时 Conc Mark Sweep GC 支持清理 PermGen 其他垃圾收集器是否支持清理 Pe
  • GitLab 管道 Docker 构建卡在 apk 上

    尝试创建一个简单的 GitLab 管道 为 Alpine Linux Openshift CLI 构建 Docker 镜像 这是代码 FROM frolvlad alpine glibc latest MAINTAINER Daniel W
  • 从嵌入的 SVG 设置 XSL FO 背景图像

    我正在创建背景文本withinXSL FO 文档是这样的
  • JQuery Mobile 刷新复选框仅有效一次 - .checkboxradio('refresh') 问题

    我遇到了一个奇怪的问题 我有一个带有复选框列的表格 我正在使用 JQuery Mobile 复选框 我希望单击一行与单击该行中的复选框相关联 JS document on pagecreate function event bindRowC
  • 如何在 Formidable (Node.js) 中取消用户上传?

    我已经研究这个问题两天了 但我被困住了 我正在使用 Node js 和 Express 并且正在尝试实现上传表单 基本上 我希望表单执行以下操作 检查文件的大小 如果太大则取消上传 当我说取消时 我的意思是防止任何进一步的数据写入磁盘并删除