使用 go 处理文件上传

2024-03-16

我最近才开始玩围棋,所以我还是个菜鸟,如果我犯了太多错误,抱歉。我已经尝试解决这个问题很长时间了,但我只是不明白发生了什么。在我的 main.go 文件中,我有一个主要函数:

func main() {
    http.HandleFunc("/", handler)
    http.HandleFunc("/submit/", submit)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

处理函数如下所示:

func handler(w http.ResponseWriter, r *http.Request) {
    data, _ := ioutil.ReadFile("web/index.html")
    w.Write(data)
}

我知道这不是服务网站的最佳方式 提交函数如下所示:

func submit(w http.ResponseWriter, r *http.Request) {
    log.Println("METHOD IS " + r.Method + " AND CONTENT-TYPE IS " + r.Header.Get("Content-Type"))
    r.ParseMultipartForm(32 << 20)
    file, header, err := r.FormFile("uploadFile")
    if err != nil {
        json.NewEncoder(w).Encode(Response{err.Error(), true})
        return
    }
    defer file.Close()

    out, err := os.Create("/tmp/file_" + time.Now().String() + ".png")
    if err != nil {
        json.NewEncoder(w).Encode(Response{err.Error(), true})
        return
    }
    defer out.Close()

    _, err = io.Copy(out, file)
    if err != nil {
        json.NewEncoder(w).Encode(Response{err.Error(), true})
        return
    }

    json.NewEncoder(w).Encode(Response{"File '" + header.Filename + "' submited successfully", false})
}

问题是当执行提交函数时,r.Method is GET and r.Header.Get("Content-Type")是一个空字符串,然后它继续直到第一个 if r.FormFile 返回以下错误:request Content-Type isn't multipart/form-data我不明白为什么 r.Method 总是 GET 并且没有 Content-Type。我尝试过以多种不同的方式执行index.html,但r.Method 始终是GET 并且Content-Type 为空。这是index.html中上传文件的函数:

function upload() {
    var formData = new FormData();
    formData.append('uploadFile', document.querySelector('#file-input').files[0]);
    fetch('/submit', {
        method: 'post',
        headers: {
          "Content-Type": "multipart/form-data"
        },
        body: formData
    }).then(function json(response) {
        return response.json()
    }).then(function(data) {
        window.console.log('Request succeeded with JSON response', data);
    }).catch(function(error) {
        window.console.log('Request failed', error);
    });
}

这是 HTML:

<input id="file-input" type="file" name="uploadFile" />

请注意,该标签不在标签内,我认为这可能是问题所在,因此我将函数和 HTML 更改为如下所示:

function upload() {
    fetch('/submit', {
        method: 'post',
        headers: {
          "Content-Type": "multipart/form-data"
        },
        body: new FormData(document.querySelector('#form')
    }).then(function json(response) {
        return response.json()
    }).then(function(data) {
        window.console.log('Request succeeded with JSON response', data);
    }).catch(function(error) {
        window.console.log('Request failed', error);
    });
}

<form id="form" method="post" enctype="multipart/form-data" action="/submit"><input id="file-input" type="file" name="uploadFile" /></form>

但这也不起作用。我用 Google 搜索了如何使用 fetch() 以及如何从 go 接收文件上传,我发现它们与我的非常相似,我不知道我做错了什么。

UPDATE:使用后curl -v -F 'uploadFile=@\"C:/Users/raul-/Desktop/test.png\"' http://localhost:8080/submit我得到以下输出:

* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> POST /submit HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.45.0
> Accept: */*
> Content-Length: 522
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=---------------------------a17d4e54fcec53f8
>
< HTTP/1.1 301 Moved Permanently
< Location: /submit/
< Date: Wed, 18 Nov 2015 14:48:38 GMT
< Content-Length: 0
< Content-Type: text/plain; charset=utf-8
* HTTP error before end of send, stop sending
<
* Closing connection 0

我正在运行的控制台go run main.go使用curl时不输出任何内容。


我设法解决了我的问题,所以在这里以防其他人需要它。感谢@JiangYD 提供使用curl 测试服务器的技巧。

TL;DR

  • I wrote http.HandleFunc("/submit/", submit)但我正在向/submit(注意缺少斜杠)
  • 不要自己指定 Content-Type,浏览器会为您指定

长答案

我按照@JiangYD所说并使用卷曲来测试服务器,我用回复更新了我的答案。我发现奇怪的是有一个 301 重定向,因为我没有把它放在那里,我决定使用以下curl命令

curl -v -F 'uploadFile=@\"C:/Users/raul-/Desktop/test.png\"' -L http://localhost:8080/submit

(注意-L)这样,curl 遵循了重定向,尽管它再次失败,因为在重定向时,curl 从 POST 切换到 GET,但通过该响应,我发现请求/submit被重定向到/submit/我记得我就是这么写的main功能。

修复后仍然失败,响应是http: no such file并通过查看net/http代码我发现这意味着该字段不存在,所以我做了一个快速测试迭代获得的所有字段名称:

for k, _ := range r.MultipartForm.File {
    log.Println(k)
}

我正在得到'uploadFile作为字段名称,我删除了curl命令中的单引号,现在它完美地上传了文件

但它并没有在这里结束,我现在知道服务器工作正常,因为我可以使用上传文件curl但是当我尝试通过托管网页上传它时,出现错误:no multipart boundary param in Content-Type.

所以我发现我应该在标头中包含边界,我将 fetch 更改为如下所示:

fetch('/submit', {
    method: 'post',
    headers: {
        "Content-Type": "multipart/form-data; boundary=------------------------" + boundary
    }, body: formData})

我这样计算边界:

var boundary = Math.random().toString().substr(2);

但我仍然遇到错误:multipart: NextPart: EOF那么如何计算边界呢?我阅读了规范https://html.spec.whatwg.org/multipage/forms.html#multipart/form-data-encoding-algorithm https://html.spec.whatwg.org/multipage/forms.html#multipart/form-data-encoding-algorithm并发现边界是由编码文件的算法计算的,在我的例子中是 FormData,FormData API 没有公开获取该边界的方法,但我发现浏览器添加了 Content-Typemultipart/form-data如果您不指定边界,则会自动设置边界,因此我从fetch打电话现在终于可以用了!

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

使用 go 处理文件上传 的相关文章

  • 如何仅在 css/html 中强制在单词之间换行?

    我只有一段普通的文本 p 标签内的 p div 标签 但只有 Firefox 可以正确显示 Firefox 打破了单词之间的界限 所有其他浏览器都会在单词中间断行 这使得阅读变得困难 这是我的意思的一个例子 火狐浏览器 工作中 This w
  • 使用文件 API 将资源加载到 Three.js 中

    我想创建导入 3D 模型以在浏览器中查看的功能 方法是使用File API http www html5rocks com en tutorials file dndfiles Three js 加载器在我托管的文件上运行良好 我的理解是加
  • 使用 JavaScript 生成 PDF 文件

    我正在尝试将 XML 数据从网页转换为 PDF 文件 并且希望能够完全在 JavaScript 中完成此操作 我需要能够绘制文本 图像和简单的形状 我希望能够完全在浏览器中完成此操作 我刚刚写了一个名为jsPDF https github
  • Chromium 嵌入式框架支持 HTML5 音频吗?

    我一直在玩 CefSharp 但似乎无法播放任何音频 我可以让音频控件出现 但它们保持冻结状态 这些是我使用的版本 Chromium 21 0 1180 0 CEF r728 CefSharp 0 12 4596 50 我先尝试了 mp3
  • 通过JS Laravel访问存储目录

    有没有办法访问storage目录 该目录已经链接到publicJS 中的目录 我正在尝试制作一个上传图片的表单 验证脚本 if request gt hasFile photos marker gt photos request gt ph
  • 有没有办法将变量从 javascript 导入到 sass 或反之亦然?

    我正在制作一个依赖于块概念的 CSS 网格系统 所以我有一个基本文件 例如 max columns 4 block width 220px block height 150px block margin 10px 它被 mixin 使用 m
  • 循环遍历元素并逐步为每个元素应用 CSS 规则

    我有一个网格布局 每个网格布局中都有不同数量的元素 我想动态添加内联grid column通过循环遍历 div 中存在的每个元素的 CSS 规则 ul 与一类 list 所以 HTML 代码的输出需要是 ul class list ul u
  • 为什么 Web Worker 性能在 30 秒后急剧下降?

    我正在尝试提高在网络工作人员中执行时脚本的性能 它旨在解析浏览器中的大型文本文件而不会崩溃 一切都运行得很好 但我注意到使用网络工作者时大文件的性能存在严重差异 于是我做了一个简单的实验 我在同一输入上运行脚本两次 第一次运行在页面的主线程
  • Google 地图 API:忽略 DirectionService 请求中的季节性限制

    我目前正在开发一张地图 其中显示两点之间的最短路线 使用不同的交通工具 我注意到 有时 例如在冬季关闭的道路不会被考虑在内 我发现我可以使用方向服务 下面的代码 忽略高速公路 收费站和渡轮 但我一生都无法弄清楚如何 是否可以忽略季节性限制
  • 如何打开弹出窗口并用父窗口中的数据填充它?

    如何使用 JavaScript jQuery 使用父页面中 JS 变量的数据填充弹出窗口 在我的示例中 我有一个文件名数组 我在父窗口中最多列出五个 如果还有更多 我想提供一个链接来打开弹出窗口并列出数组中的每个帖子 因此 如果我打开一个包
  • 即使在包裹后也具有等宽的弹性项目

    是否可以制作一个像这样的纯 CSS 解决方案 物品有一些min width 它们应该动态增长以填充所有容器宽度 然后换行到新行 列表中的所有项目都应具有相同的宽度 现在看起来是这样的 这就是我希望它看起来像的样子 我已经手动管理这些底部项目
  • 如何处理requireJs超时错误?

    我正在使用 require js 作为加载框架编写一个移动混合应用程序 我遇到加载错误的问题 我想做的是在设备离线且无法下载在屏幕上显示地图所需的 google 地图 API 脚本时设置后备解决方案 我得到的只是 Uncaught Erro
  • HTML 元素的默认背景颜色是什么?白色还是透明?

    我只是被一个简单的问题困住了 想弄清楚 HTML 元素的默认背景颜色是什么 是白色的还是透明的 默认背景颜色是透明的 看这里 https developer mozilla org en docs Web CSS background co
  • Ember Data 中出现“超出最大调用堆栈大小”错误的原因可能是什么?

    Ember 发布新版本 3 6 0 后 我开始在控制台中收到错误 rsvp js 24 未捕获 RangeError 超出最大调用堆栈大小 在 WeakMap get 在 getCacheFor metal js 25 在 Computed
  • JavaScript 数组扩展语法的时间复杂度是多少?

    我想知道在 JavaScript 中使用数组扩展的时间复杂度是多少 是线性 O n 还是常数 O 1 下面的语法示例 let lar Math max nums 传播称为 Symbol iterator 有关对象的属性 对于数组 这将迭代数
  • 如何让div与包含td的高度相匹配?

    我沿着桌子的一排布置了三个 面板 一个比另外两个高 我希望所有三个面板都与最高的一个的高度相匹配 我尝试将 div 的样式设置为 height 100 但是即使包含的 tds 增长 短面板仍然很短 我的 HTML 是由 JSF 生成的 因此
  • HTML 输入 - 名称与 ID [重复]

    这个问题在这里已经有答案了 使用 HTML 时
  • Node.js - 重载函数

    有没有一种方法可以重载node js中的函数 类似于 noSuchMethod https developer mozilla org en JavaScript Reference Global Objects Object noSuch
  • 在 HTML5 iOS 7 / iOS 8 中显示十进制键盘

    经过几个小时的搜索后 我只是有一个简单的问题 是否有可能在网络浏览器输入字段中显示小数键盘 input type number 只显示数字 但我需要在左下角使用逗号或点 我尝试过任何事情 pattern step等等 但没有显示十进制键盘
  • Flowtype 属性“msg”缺失为 null 或未定义

    我发现 Flow 很难用 我明白那个Array find可以返回或未定义 因此 通过阅读以下内容 github Array find on Array 引发 https github com facebook flow issues 351

随机推荐

  • 使用 gradle 构建 android 应用程序时 Lint 失败

    我用 android studio 创建了一个应用程序 但每次我尝试使用命令gradle build构建应用程序时 它显示 lint failed 当我检查 gradle build 的调试信息时 它说 21 10 26 215 DEBUG
  • Lua:字符串中的换行符

    我一直在开发一个格式化程序 它将接受一个长字符串并将其格式化为一系列在特定字符限制内的单词处断开的行 例如 他吃面包每 8 个字符断开一次 将返回类似以下内容的内容 He eats the bread 这是因为 He eats 包含 7 个
  • 如何使用 VBA 在众多文本 .log 文件之一中查找特定字符串?

    这是我迄今为止查找文件夹中所有日志文件的代码 但我需要能够在每个文件中找到特定的字符串 如果在一个文件中找到它 则停止查找并退出循环并报告它所在的文件名 打开文件和搜索文件的方法似乎有很多 我不知道哪种方法最好 而且我通常不使用 VBA 但
  • 正向lookbehind后跟逗号分隔列表

    我正在寻找是否有一种方法可以在积极的向后查找之后为每个逗号分隔的列表获取匹配组 例如 summertime swimming running tanning 正则表达式 到目前为止 lt summertime s Returns swimm
  • libVLCSharp 无法创建 MediaList

    我正在玩 libVLCSharp 发现了一个有线行为 实际上 我创建媒体并使用 MediaPlayer 播放它没有任何问题 但是 当我尝试从 MediaList 创建媒体时 它会中断并显示以下消息 无法在本机端执行实例化 确保你 在您的系统
  • WIF 中的主动和被动联合

    我试图了解 WIF 中主动联合和被动联合之间的区别 如果依赖方 RP 是 WCF 服务而不是 ASP NET 应用程序 则似乎可以使用主动联合 如果 RP 是 ASP NET 应用程序 则可以使用被动联合 这准确吗 因此 在 ASP NET
  • Django 中不同应用程序的不同数据库[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我的 Django 站点中有多个应用
  • 组织 Javascript 库和 CSS 文件夹结构的最佳实践[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 如何在 Web 应用程序中组织 js 和 css 文件夹 我当前的项目结构是这样的 root assets js lib css img ind
  • Apache Commons JCI 重新加载类加载器

    有人有使用 Apache Commons JCI API 的 ReloadingClassLoader 的经验吗 唯一的使用示例可以在以下页面中找到 http commons apache org jci usage html http c
  • 如何在 UIWebview 中保存本地加载的 HTML 文件

    我正在使用 UIWebView 编写一个富文本编辑器 为此 我使用了一个模板文件作为启动器 然后 当用户完成编辑但尚未发布时 我想将当前内容保存到备份 html 文件中 以防应用程序损坏 我怎么做 给你 伙计 NSFileHandle fi
  • 有没有办法阻止 HTML access key="" 被激活?

    I tried preventDefault 但我还没有成功 我缺少什么吗 如果可能的话 我会尝试全局禁用它 例如在window 似乎没有办法阻止事件触发 唯一的选择似乎是在您不希望它们工作时暂时删除 accesskey 属性 就是这样jQ
  • csproj 文件中 元素的用途是什么

    当我编辑 Web 应用程序项目时 Visual Studio 2017 15 3 1 添加
  • Angular 4 setTimeout() 具有可变延迟和等待

    我有一个事件列表timestamp 我想要的是根据timestamp 添加延迟 delay timestamp t 1 timstamp t 我知道这不太适合setTimeout 但是有一个解决方法 如果超时是恒定的 但在我的情况下不是 是
  • 创建 Openstreetmap 提取的 mbtiles 文件的最简单方法?

    我正在创建一个使用在线和离线地图的 iPhone 旅行应用程序 对于离线地图 我希望允许用户下载他们感兴趣的区域 例如伦敦 的 mbtiles 文件 该地图应包含已在 OpenStreetmap 中找到的道路等信息 我知道以下网站http
  • pandas groupby 根据条件替换

    我有一个数据集结构如下 index country city Data 0 AU Sydney 23 1 AU Sydney 45 2 AU Unknown 2 3 CA Toronto 56 4 CA Toronto 2 5 CA Ott
  • Flutter:升级Play商店版本号

    我已经使用 flutter 在 Play 商店上发布了一个应用程序 现在我想上传该应用程序的新版本 我正在尝试更改版本代码 flutter 构建 apk build name 1 0 2 build number 3 或像这样更改 loca
  • 如何在 Java 中检查文件权限(独立于操作系统)

    我有以下代码片段 public class ExampleClass public static void main String args throws FileNotFoundException String filePath args
  • 加载 word2vec 时出现 UnicodeDecodeError 错误

    详细描述 我开始使用词嵌入 并发现了大量有关它的信息 到目前为止 我知道我可以训练自己的词向量或使用以前训练过的词向量 例如 Google 或 Wikipedia 的词向量 这些向量可用于英语 但对我来说没有用 因为我正在处理以下语言中的文
  • WSO2 Identity Server 5.1.0 未在 SAML 响应中返回用户声明

    在尝试新版本的 WSO2 Identity Server 5 1 0 时 我在返回 SAML 响应中的声明时遇到问题 虽然这在 WSO2 IS 5 0 0 SP1 中有效 我已经映射了所需的声明并将它们添加到我的 SP 此外我还配置了 SP
  • 使用 go 处理文件上传

    我最近才开始玩围棋 所以我还是个菜鸟 如果我犯了太多错误 抱歉 我已经尝试解决这个问题很长时间了 但我只是不明白发生了什么 在我的 main go 文件中 我有一个主要函数 func main http HandleFunc handler