核心原理

当你通过网页表单上传文件时,浏览器会将表单数据(包括文件内容和其他文本字段)打包成一个特殊的格式,即 multipart/form-data,这个格式由多个部分组成,每个部分之间由一个唯一的边界字符串分隔。

易语言 通过post向网页上传文件
(图片来源网络,侵删)
  • 文本字段部分:一个名为 username 的字段,值是 testuser,它会以特定的格式编码。
  • 文件部分:文件名、文件内容类型(Content-Type)和文件本身的内容也会被编码成一个部分。

我们的任务就是模拟这个打包过程,然后通过 HTTP POST 请求发送给服务器。


准备工作:需要易语言模块

由于易语言本身没有内置处理复杂 HTTP 请求和文件编码的模块,我们需要使用第三方模块,最常用和推荐的是 网络通讯支持库 或类似的模块,它们封装了底层的网络请求和文件处理功能。

你可以从易语言的官方论坛或第三方资源网站下载并安装这类支持库,以下示例将基于一个功能较为全面的网络通讯模块进行讲解。


详细步骤与代码示例

假设我们要向一个服务器上传一个名为 mydata.txt 的文件,并且这个表单还有一个文本字段 description

易语言 通过post向网页上传文件
(图片来源网络,侵删)

步骤 1:创建窗口和控件

在易语言中创建一个“Windows 窗口程序”,并添加以下控件:

  1. 编辑框:用于输入要上传的文件路径,我们可以给它一个标识符,#文件路径
  2. 按钮:用于触发“选择文件”操作,标识符可为 #选择文件
  3. 按钮:用于触发“上传文件”操作,标识符可为 #上传
  4. 超级编辑框:用于显示上传过程中的状态信息和最终结果,标识符可为 #日志
  5. 用于提示信息。

步骤 2:编写“选择文件”按钮的代码

双击“选择文件”按钮,编写如下代码,用于打开一个文件选择对话框,并将用户选择的文件路径填入编辑框。

.版本 2
.程序集 窗口程序集_启动窗口
.子选择文件_被单击 ()
    .如果真 (选择文件 (“请选择要上传的文件”, , “文本文件|*.txt|所有文件|*.*”, , , , , , , , ) = 真)
        .计次循环首 (取数组成员数 (选择文件_返回路径数组), i)
            文件路径.内容 = 选择文件_返回路径数组 [i]
        .计次循环尾 ()
    .如果真结束
.子结束

步骤 3:编写“上传”按钮的核心代码

这是最关键的部分,双击“上传”按钮,编写如下代码:

.版本 2
.程序集 窗口程序集_启动窗口
.子 上传_被单击 ()
    .如果真 (文件路径.内容 = "")
        信息框 (“请先选择要上传的文件!”, 0, , )
        返回 ()
    .如果真结束
    .局部变量 上传地址, 文本型
    .局部变量 边界, 文本型
    .局部变量 表单数据, 文本型
    .局部变量 文件名, 文本型
    .局部变量 文件内容, 字节集
    .局部变量 HTTP请求, 对象
    ' --- 1. 准备上传地址和边界 ---
    ' 替换成你实际的上传接口地址
    上传地址 = “http://www.example.com/upload.php”
    ' 边界字符串是任意的,只要确保在数据中不会出现即可
    边界 = “----WebKitFormBoundary7MA4YWxkTrZu0gW”
    ' --- 2. 准备表单数据 ---
    ' 使用模块提供的函数来构建 multipart/form-data 数据
    ' 通常模块会有一个“创建表单数据”或类似的函数,接收边界作为参数
    ' 假设模块名为 '网络通讯支持库'
    .如果真 (取变量类型 (创建表单数据) = 0) ' 检查函数是否存在
        .如果真 (假)
            信息框 (“未找到 '创建表单数据' 函数,请检查网络模块是否正确安装!”, 16, , )
            返回 ()
        .如果真结束
    .否则
        表单数据.创建 (边界) ' 假设这个函数返回一个对象或文本变量
    .如果结束
    ' --- 3. 添加文本字段 (可选) ---
    ' 添加一个名为 'description' 的文本字段
    ' 假设模块有 '添加文本字段' 方法
    表单数据.添加文本字段 (“description”, “这是我的测试文件”)
    ' --- 4. 添加文件 ---
    ' 获取文件名,不包含路径
    文件名 = 取文件名 (文件路径.内容)
    ' 读取文件内容为字节集
    文件内容 = 读入文件 (文件路径.内容)
    ' 假设模块有 '添加文件' 方法,通常需要字段名、文件名、文件内容、文件类型
    ' 文件类型 'application/octet-stream' 是通用二进制类型,如果知道具体类型(如图片)可以指定
    表单数据.添加文件 (“filedata”, 文件名, 文件内容, “application/octet-stream”)
    ' --- 5. 结束表单数据 ---
    ' 在所有字段添加完毕后,需要添加结束边界
    表单数据.结束 ()
    ' --- 6. 发送HTTP POST请求 ---
    ' 创建HTTP请求对象
    HTTP请求.创建 ()
    HTTP请求.请求地址 = 上传地址
    HTTP请求.请求方法 = “POST”
    ' 设置请求头,Content-Type 必须包含 boundary
    HTTP请求.请求头 (“Content-Type”) = “multipart/form-data; boundary=” + 边界
    ' 设置请求体为我们刚刚构建的表单数据
    HTTP请求.请求体 = 表单数据.取数据 ()
    ' 显示日志
    日志.加入文本 (“正在上传文件: ” + 文件名 + #换行符)
    日志.加入文本 (“上传地址: ” + 上传地址 + #换行符)
    ' 发送请求并获取响应
    .如果真 (HTTP请求.发送 ())
        ' --- 7. 处理服务器响应 ---
        .局部变量 响应文本, 文本型
        .局部变量 状态码, 整数型
        响应文本 = HTTP请求.取响应文本 ()
        状态码 = HTTP请求.取状态码 ()
        日志.加入文本 (“上传成功!服务器返回状态码: ” + 到文本 (状态码) + #换行符)
        日志.加入文本 (“服务器响应: ” + 响应文本 + #换行符)
    .否则
        ' 上传失败
        日志.加入文本 (“上传失败!错误信息: ” + HTTP请求.取错误信息 () + #换行符)
    .如果真结束
    ' 释放对象
    HTTP请求.销毁 ()
.子结束

代码解释

  1. 上传地址边界:

    易语言 通过post向网页上传文件
    (图片来源网络,侵删)
    • 上传地址:这是你目标服务器接收文件的那个URL,你需要替换成你自己的。
    • 边界:一个用于分隔表单数据中不同部分的字符串,它可以是任意唯一字符串,通常以 ----WebKitFormBoundary 开头是现代浏览器的习惯,关键是服务器能正确识别它。
  2. 创建表单数据:

    • 这通常是网络模块提供的一个核心函数,它初始化一个用于存放 multipart/form-data 格式数据的对象或文本变量,我们传入 边界 作为参数。
  3. 添加文本字段:

    • 如果你的表单除了文件还有其他普通文本输入(如用户名、描述等),就使用这个方法。
    • 参数通常是:字段名, 字段值
  4. 添加文件:

    • 这是上传文件的核心方法。
    • 参数通常是:字段名 (在服务器端用来接收这个文件的参数名,如 PHP 的 $_FILES['filedata'])、文件名 (用户看到的文件名)、 (从文件中读取的字节集)、文件类型 (MIME 类型,如 image/jpeg, text/plain 等。application/octet-stream 是一个通用的安全值)。
  5. 结束:

    在添加完所有字段后调用,它会自动在数据末尾添加结束边界,标志着整个表单数据的结束。

  6. 设置请求头:

    • Content-Type: multipart/form-data; boundary=...必须的,它告诉服务器这次提交的数据是 multipart 格式,并且边界是什么,如果缺少这个头,服务器将无法正确解析你发送的数据。
  7. 发送请求与处理响应:

    • 我们将构建好的 表单数据 作为 请求体 发送。
    • 服务器处理完成后会返回一个响应,我们通过 取响应文本() 获取服务器返回的任何信息(JSON格式的成功/失败消息,或者一个简单的 "OK" 字符串)。
    • 通过 取状态码() 可以了解 HTTP 请求的结果,如 200 (成功), 404 (未找到), 500 (服务器内部错误) 等。

重要提示

  • 模块差异:不同的网络模块(如 网络通讯支持库易语言Http模块 等)其 API(函数名、参数)可能略有不同,请务必根据你所使用的模块的文档来调整代码,有的模块可能叫 构建POST数据 而不是 创建表单数据
  • 服务器端:这个示例只涉及客户端(易语言)的代码,你的服务器端(如 PHP, Java, Python, Node.js 等)必须有相应的代码来接收和处理这个 multipart/form-data 请求,如果你没有服务器,可以使用一些在线的 HTTP 请求测试工具(如 httpbin.org)来验证你的上传代码是否正确。
  • 调试:如果上传失败,最好的调试方法是:
    1. 使用浏览器开发者工具(F12)的 "Network" 面板,手动通过网页表单上传一次文件,查看 "Headers" 中的 Request URL, Request Method, Content-Type 等信息。
    2. 查看 "Payload" 或 "Request" 面板,复制原始的请求数据。
    3. 将易语言代码中构建的 表单数据请求头 与浏览器中的进行对比,看是否一致,这是定位问题最有效的方法。