目录

  1. 什么是 POST 请求?
  2. 易语言实现 POST 的核心组件
  3. 最简单的 POST 请求(提交表单数据)
  4. 向 API 服务器发送 JSON 数据
  5. 处理返回的数据(获取网页源码)
  6. 处理更复杂的请求(添加请求头 Headers)
  7. 常见问题与解决方案
  8. 总结与进阶

什么是 POST 请求?

在开始之前,我们先简单理解一下 POST 请求。

易语言post网页访问教学
(图片来源网络,侵删)
  • GET 请求:就像你在浏览器地址栏输入网址并回车,你请求的数据会直接显示在 URL 后面(http://example.com/search?q=易语言),特点是简单、直观,但不适合传输敏感或大量数据。
  • POST 请求:就像你在网页上填写一个表单并点击“提交”,你填写的数据(用户名、密码、文章内容等)被“打包”在请求的“身体”(Body)里发送给服务器,用户看不到这些数据,更安全,且可以传输大量数据。

POST 请求主要用于向服务器提交数据,而不是获取数据。


易语言实现 POST 的核心组件

在易语言中,我们主要使用两个外部 DLL(动态链接库)来完成网络请求:

  1. WinINet.dll:这是 Windows 系统自带的网络库,功能相对基础,但足以处理大部分 HTTP/HTTPS 请求,它易于使用,是初学者的首选。
  2. libcurl.dll:这是一个功能非常强大的开源网络库,支持几乎所有网络协议,功能远超 WinINet,但配置和使用相对复杂一些。

本教程将重点介绍更简单、更通用的 WinINet.dll 方法。


教学一:最简单的 POST 请求(提交表单数据)

假设我们要向一个网站提交一个简单的表单,包含两个字段:usernamepassword

易语言post网页访问教学
(图片来源网络,侵删)

目标: 模拟提交 username=admin&password=123456 这样的数据。

步骤 1:创建易语言程序

  1. 打开易语言。
  2. 新建“Windows 窗口程序”。
  3. 在窗口上放置一个“按钮”组件,将其“标题”改为“执行 POST 请求”。

步骤 2:编写核心代码

双击“执行 POST 请求”按钮,进入代码编辑区,编写如下代码:

.版本 2
.程序集 窗口程序集_启动窗口
.子程序 __启动窗口_创建完毕
.子程序 __按钮1_被单击, , 公开
.局部变量 hInternet, 整数型
.局部变量 hConnect, 整数型
.局部变量 hRequest, 整数型
.局部变量 PostData, 文本型
.局部变量 Encoding, 整数型
.局部变量 BytesSent, 整数型
.局部变量 Buffer, 文本型, , "0"
.局部变量 BufferSize, 整数型
.局部变量 BytesRead, 整数型
' 1. 初始化 WinINet
hInternet = InternetOpenA ("MyPostApp", 1, 0, 0, 0)
(hInternet = 0) 则
    信息框 ("初始化网络失败!", 0, , )
    返回 ()
结束如果
' 2. 连接到目标服务器
' 请将 "http://example.com/login.php" 替换为你的目标URL
hConnect = InternetConnectA (hInternet, "example.com", 80, 0, 0, 3, 0, 0)
(hConnect = 0) 则
    信息框 ("连接服务器失败!", 0, , )
    InternetCloseHandle (hInternet)
    返回 ()
结束如果
' 3. 打开一个 HTTP 请求
hRequest = HttpOpenRequestA (hConnect, "POST", "/login.php", 0, 0, 0, 0, 0)
(hRequest = 0) 则
    信息框 ("打开请求失败!", 0, , )
    InternetCloseHandle (hConnect)
    InternetCloseHandle (hInternet)
    返回 ()
结束如果
' 4. 准备要发送的数据 (表单数据)
PostData = "username=admin&password=123456"
' 5. 发送请求
Encoding = InternetSetOptionA (hInternet, 65, 0, 0) ' 设置编码选项,通常为0或65
BytesSent = HttpSendRequestA (hRequest, 0, 0, 到字节集 (PostData), 取文本长度 (PostData))
(BytesSent = 0) 则
    信息框 ("发送请求失败!", 0, , )
    InternetCloseHandle (hRequest)
    InternetCloseHandle (hConnect)
    InternetCloseHandle (hInternet)
    返回 ()
结束如果
' 6. 接收服务器返回的数据 (可选)
' 我们通常需要知道服务器是否成功处理了我们的请求
BufferSize = 4096
.循环判断首 ()
    Buffer = 取空白文本 (BufferSize)
    BytesRead = InternetReadFile (hRequest, 到字节集 (Buffer), BufferSize, 0)
    (BytesRead = 0) 则
        跳出循环 ()
    否则
        ' 将读取到的数据追加到结果文本中
        ' 注意:这里可能需要对Buffer进行截断,因为ReadFile可能会读取到多余的数据
        ' 简单处理:直接显示
        信息框 ("服务器返回部分数据:" + 取文本左边 (Buffer, BytesRead), 0, , )
    结束如果
.循环尾 ()
' 7. 关闭所有句柄,释放资源 (非常重要!)
InternetCloseHandle (hRequest)
InternetCloseHandle (hConnect)
InternetCloseHandle (hInternet)
信息框 ("POST 请求执行完毕!", 0, , )

代码讲解:

  1. InternetOpenA: 初始化 WinINet 库,告诉我们要用这个库来上网。"MyPostApp" 是我们给程序起的一个名字。
  2. InternetConnectA: 建立到服务器的连接,参数包括服务器地址 ("example.com")、端口 (80 是 HTTP,443 是 HTTPS)、请求类型 (3 表示 INTERNET_SERVICE_HTTP)。
  3. HttpOpenRequestA: 创建一个具体的 HTTP 请求,我们指定了方法是 "POST",以及请求的路径 ("/login.php")。
  4. PostData: 这就是我们要发送的核心数据,它是一个标准的 key=value&key2=value2 格式的字符串。
  5. HttpSendRequestA: 真正执行发送操作,我们将 PostData 转换成字节集后发送出去。
  6. InternetReadFile: 发送请求后,服务器会返回一个响应(比如登录成功或失败的提示),这个函数就是用来读取服务器返回的数据的,我们通常用一个循环来读取所有数据。
  7. InternetCloseHandle: 非常重要! 每次使用完 InternetOpenInternetConnectHttpOpenRequest 返回的句柄后,都必须用这个函数关闭它,否则会造成系统资源泄漏。

教学二:向 API 服务器发送 JSON 数据

现在很多 Web API 都要求使用 JSON 格式来传输数据。

目标: 向 API 发送一个 JSON 对象:{"name": "张三", "age": 30}

易语言post网页访问教学
(图片来源网络,侵删)

修改代码:

只需要修改 PostData 的赋值部分,并添加一个 Content-Type 请求头。

' ... (前面的代码不变) ...
' 3. 打开一个 HTTP 请求
hRequest = HttpOpenRequestA (hConnect, "POST", "/api/user", 0, 0, 0, 0, 0)
(hRequest = 0) 则
    ' ... (错误处理) ...
结束如果
' --- 新增部分:添加请求头 ---
.局部变量 Headers, 文本型
Headers = "Content-Type: application/json" + #换行符 + #换行符 ' #换行符 + #换行符 是关键,表示头部的结束
HttpAddRequestHeadersA (hRequest, Headers, 取文本长度 (Headers), 20)
' --- 新增部分结束 ---
' 4. 准备要发送的数据 (JSON数据)
PostData = "{""name"": ""张三"", ""age"": 30}" ' 注意:易语言里字符串内的双引号要用两个双引号表示
' ... (后面的代码不变) ...

代码讲解:

  1. Content-Type: application/json: 这是一个 HTTP 请求头,它告诉服务器:“我发送给你的数据格式是 JSON”,服务器看到这个头,就会用相应的方式来解析 PostData
  2. HttpAddRequestHeadersA: 这个函数用于向请求中添加自定义的头部信息。20HTTP_ADDREQ_FLAG_ADD 的值,表示添加头部。
  3. PostData: 这里我们直接赋值一个 JSON 字符串,注意在易语言字符串中,一个双引号 必须写成两个 来表示。

教学三:处理返回的数据(获取网页源码)

我们之前的例子只是简单弹出了返回数据,通常我们想把服务器返回的整个响应(HTML 源码、JSON 响应)保存到一个变量里,以便后续处理。

修改代码:

修改接收数据的循环部分。

' ... (发送请求前的代码不变) ...
.局部变量 ResponseData, 文本型 ' 用于存放完整返回数据
ResponseData = ""
' 6. 接收服务器返回的数据
BufferSize = 4096
.循环判断首 ()
    Buffer = 取空白文本 (BufferSize)
    BytesRead = InternetReadFile (hRequest, 到字节集 (Buffer), BufferSize, 0)
    (BytesRead = 0) 则
        跳出循环 ()
    否则
        ' 将读取到的数据追加到 ResponseData 中
        ' 使用取文本左边来确保只添加实际读取到的字节
        ResponseData = ResponseData + 取文本左边 (Buffer, BytesRead)
    结束如果
.循环尾 ()
' 显示完整的返回数据
调试输出 (ResponseData)
' ... (关闭句柄的代码不变) ...

代码讲解:

我们创建了一个 ResponseData 变量,在循环中,每次从服务器读取一小块数据,就把它追加到 ResponseData 的末尾,循环结束后,ResponseData 就包含了服务器返回的全部内容。


教学四:处理更复杂的请求(添加请求头 Headers)

有些网站会检查你的请求来源,或者需要特定的认证信息,这时就需要添加更多的请求头。

常用请求头:

  • User-Agent: 模拟浏览器访问,很多网站会拒绝非浏览器的访问。
  • Referer: 告诉服务器你是从哪个页面跳转过来的。
  • Cookie: 用于保持登录状态等。

修改代码:

在发送请求之前,使用 HttpAddRequestHeadersA 添加多个头。

' ... (在 HttpOpenRequestA 之后,HttpSendRequestA 之前添加) ...
.局部变量 Headers, 文本型
' 添加 User-Agent 和 Referer
Headers = "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" + #换行符
Headers = Headers + "Referer: http://example.com/index.html" + #换行符 + #换行符
HttpAddRequestHeadersA (hRequest, Headers, 取文本长度 (Headers), 20)
' 如果需要发送 Cookie
' Headers = "Cookie: sessionid=abcdef123456; username=admin" + #换行符 + #换行符
' HttpAddRequestHeadersA (hRequest, Headers, 取文本长度 (Headers), 20)
' ... (然后进行 HttpSendRequestA) ...

常见问题与解决方案

  1. 问题:连接服务器失败 (InternetConnectA 返回 0)

    • 原因1: 网络不通,检查你的电脑是否能正常上网。
    • 原因2: 服务器地址或端口错误,确认 URL 是否正确,端口是否正确(HTTP是80,HTTPS是443)。
    • 原因3: 服务器防火墙或你的本地防火墙阻止了连接。
  2. 问题:发送请求失败 (HttpSendRequestA 返回 0)

    • 原因1: 没有正确设置 Content-Type,特别是发送 JSON 或 XML 数据时,这个头是必须的。
    • 原因2: 服务器验证失败,比如登录时用户名密码错误,服务器会直接拒绝请求,这也是一种“失败”,但程序会继续执行。
    • 原因3: 数据编码问题,确保你的 PostData 编码是正确的(通常是 UTF-8)。WinINet 默认使用系统编码,有时需要手动处理,对于中文,最好确保你的易语言源码文件和运行环境都是 UTF-8 编码。
  3. 问题:返回的数据是乱码

    • 原因: 服务器返回的编码(如 Content-Type: text/html; charset=utf-8)和易语言默认的编码不一致。
    • 解决方案: 检查返回的 ResponseData 中是否包含 charset 信息,如果包含,且不是 GBK(易语言默认),可能需要进行编码转换,对于简单的页面,直接另存为 UTF-8 文件查看通常可以解决。
  4. 问题:访问 HTTPS 网站失败

    • 原因: WinINet 默认会验证 SSL 证书,如果目标网站的证书有问题(比如自签名证书),验证就会失败。
    • 解决方案:InternetConnectA 之前,可以调用 InternetSetOptionA 来忽略证书验证(注意:这会降低安全性,仅用于测试!)。
      .局部变量 dwFlags, 整数型
      dwFlags = 0x00008000 ' INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
      InternetSetOptionA (hInternet, 63, &dwFlags, 4) ' 63 是 INTERNET_OPTION_SECURITY_FLAGS

总结与进阶

通过以上教学,你应该已经掌握了使用易语言进行 POST 请求的基本方法。

  • 核心流程: InternetOpen -> InternetConnect -> HttpOpenRequest -> HttpAddRequestHeaders (可选) -> HttpSendRequest -> InternetReadFile -> InternetCloseHandle
  • 关键点:
    • PostData 的格式(表单 key=value 或 JSON)。
    • Content-Type 请求头的设置要与 PostData 格式匹配。
    • 务必记得关闭所有句柄,防止内存泄漏。
    • 学会调试,使用 调试输出() 查看发送的数据和接收的数据,是解决问题的最好方法。

进阶方向:

  • 使用 libcurl:当 WinINet 无法满足需求时(例如需要更高级的代理支持、更精细的控制),可以学习使用 libcurl.dll,它的功能更强大,但学习曲线也更陡峭。
  • 异步请求:上面的代码是同步的,会阻塞你的程序界面,如果请求需要很长时间,程序界面会“卡死”,可以学习使用 InternetOpenUrl 的回调函数模式来实现异步请求,让程序在等待网络响应时仍然能响应用户操作。
  • 封装成子程序:将上述代码封装成一个通用的“执行POST请求”的子程序,传入 URL、数据、请求头等参数,可以极大提高代码的复用性。

希望这个详细的教学对你有帮助!祝你编程愉快!