核心概念

在开始之前,我们先理解几个核心概念:

易语言网页访问带cookie
(图片来源网络,侵删)
  1. HTTP 请求: 当你访问一个网页时,你的浏览器(客户端)会向服务器发送一个 HTTP 请求,这个请求包含了方法(如 GET、POST)、URL、请求头、请求体(如果是 POST 请求)等信息。
  2. 响应: 服务器收到请求后,会返回一个 HTTP 响应,这个响应包含了状态码(如 200 表示成功)、响应头和响应体(通常是网页的 HTML 内容)。
  3. Cookie: Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器发起请求时被携带并发送到服务器上,主要用于会话管理、记录用户状态等。
  4. 工作流程:
    • 第一步(登录): 向登录接口发送一个 POST 请求,包含用户名和密码,如果登录成功,服务器会在响应头中包含一个 Set-Cookie 字段,用来设置你的登录凭证(Session ID 等)。
    • 第二步(携带 Cookie 访问): 浏览器会自动保存这个 Cookie,当你再次访问该网站的其他页面时,请求头中会自动带上这个 Cookie,服务器识别出你的身份后,就会返回你需要的数据。

在易语言中,我们需要手动模拟这个过程:先发送登录请求并获取返回的 Cookie,然后在下一次请求中手动将这个 Cookie 添加到请求头里。


使用 网页访问 插件(最简单,但灵活性较差)

易语言自带一个“网页访问”支持库,它封装了底层的 HTTP 请求,使用起来非常简单,适合处理简单的 GET 请求。

特点:

  • 优点: 代码量少,简单易用。
  • 缺点: 功能有限,难以处理复杂的 POST 请求、自定义请求头、以及获取和设置 Cookie。

示例代码:

易语言网页访问带cookie
(图片来源网络,侵删)

这个例子演示了如何访问一个页面,并手动在请求头中添加 Cookie。

.版本 2
.程序集 窗口程序集_启动窗口
.子 _按钮_访问网页_被单击 ()
    .局部变量 html_text, 文本型
    .局部变量 http_cookie, 文本型
    ' --- 1. 假设我们已经通过其他方式获取到了 Cookie ---
    ' 这个 Cookie 通常是 "key1=value1; key2=value2" 的格式
    http_cookie = "JSESSIONID=1234567890ABCDEF; username=mytestuser"
    ' --- 2. 创建一个网页访问对象 ---
    .(真)
        .计次循环首 (1, i)
            .局部变量 访问对象, 对象
            访问对象.创建 ("网页访问.创建", , 假)
            ' --- 3. 设置请求头,手动添加 Cookie ---
            ' "Cookie" 是请求头的键,http_cookie 是我们准备好的值
            访问对象.取网页_请求头_添加 ("Cookie", http_cookie)
            ' --- 4. 发送 GET 请求 ---
            ' 注意:这里的网址需要替换成你想要访问的、需要 Cookie 的页面
            html_text = 访问对象.取网页 ("http://example.com/protected_page.html", , , , )
            ' --- 5. 显示结果 ---
            .(寻找 (html_text, "欢迎", , 假) > 0)
                编辑框_结果.内容 = "访问成功!页面内容包含 '欢迎'。"
                编辑框_结果.内容 = 编辑框_结果.内容 + #换行符 + "获取到的HTML内容(部分):" + #换行符 + 取文本左边 (html_text, 200)
            .否则
                编辑框_结果.内容 = "访问失败或页面未包含 '欢迎' 字样。"
                编辑框_结果.内容 = 编辑框_结果.内容 + #换行符 + "获取到的HTML内容:" + #换行符 + html_text
            .如果结束
            ' 释放对象
            访问对象.销毁 ()
        .计次循环尾 ()
    .否则
        信息框 ("创建网页访问对象失败!", 0, , )
    .如果结束
.结束子

说明:

  • 这个方法的关键在于 访问对象.取网页_请求头_添加 ("Cookie", http_cookie) 这一行。
  • 最大的难点:这个方法无法自动从服务器的响应中获取 Set-Cookie,你必须先通过其他工具(如浏览器开发者工具 F12)手动登录一次,复制出 Cookie,然后硬编码到你的易语言程序中,这显然非常不方便。

使用 WinINet API(推荐,功能强大)

WinINet 是 Windows 自带的网络编程接口,功能比“网页访问”插件强大得多,可以完全控制 HTTP 请求和响应,包括获取和设置 Cookie,这是最常用和推荐的方法。

特点:

易语言网页访问带cookie
(图片来源网络,侵删)
  • 优点: 功能强大,灵活可控,可以完美模拟登录和携带 Cookie 的全过程。
  • 缺点: 代码相对复杂,需要直接调用 DLL 函数。

实现步骤:

  1. 声明 API 函数: 在程序集的“子程序集_启动窗口”之前声明所有需要用到的 WinINet API 函数。
  2. 发送登录请求: 调用 HttpOpenRequest, HttpAddRequestHeaders, HttpSendRequest 等函数发送登录请求(通常是 POST)。
  3. 读取响应头: 调用 HttpQueryInfo 函数读取服务器返回的响应头,从中提取 Set-Cookie 的值。
  4. 保存 Cookie: 将提取到的 Cookie 保存到一个变量中。
  5. 发送后续请求: 再次创建 HTTP 请求,并在调用 HttpSendRequest 之前,使用 HttpAddRequestHeaders 将之前保存的 Cookie 添加到请求头中。
  6. 读取响应体: 调用 InternetReadFile 循环读取服务器返回的 HTML 数据。

完整示例代码(使用 WinINet API 模拟登录并访问)

这是一个完整的、可运行的示例,模拟向一个测试网站发送登录请求,然后携带返回的 Cookie 访问用户中心。

.版本 2
.程序集 窗口程序集_启动窗口
.子 _按钮_登录并访问_被单击 ()
    .局部变量 hInternet, 整数型
    .局部变量 hConnect, 整数型
    .局部变量 hRequest, 整数型
    .局部变量 dwSize, 整数型
    .局部变量 lpBuffer, 文本型, , "0"
    .局部变量 nResult, 整数型
    .局部变量 sessionCookie, 文本型
    ' --- 1. 初始化 WinINet ---
    hInternet = InternetOpen ("WinINet-EasyExample", 1, , , 0) ' INTERNET_OPEN_TYPE_PRECONFIG
    .(hInternet = 0)
        信息框 ("InternetOpen 失败!", 0, , )
        返回 ()
    .如果结束
    ' --- 2. 连接到服务器 ---
    ' 请将 "httpbin.org" 替换为你自己的目标服务器域名
    hConnect = InternetConnect (hInternet, "httpbin.org", 80, , , 3, 0, 0) ' INTERNET_SERVICE_HTTP
    .(hConnect = 0)
        信息框 ("InternetConnect 失败!", 0, , )
        InternetCloseHandle (hInternet)
        返回 ()
    .如果结束
    ' --- 3. 打开一个请求 (模拟登录) ---
    ' 我们使用 httpbin.org/post 作为示例,它会 POST 回收到的所有数据
    hRequest = HttpOpenRequest (hConnect, "POST", "/post", , , , , 0)
    .(hRequest = 0)
        信息框 ("HttpOpenRequest 失败!", 0, , )
        InternetCloseHandle (hConnect)
        InternetCloseHandle (hInternet)
        返回 ()
    .如果结束
    ' --- 4. 添加请求头 (模拟表单提交) ---
    HttpAddRequestHeaders (hRequest, "Content-Type: application/x-www-form-urlencoded", -1, HTTP_ADDREQ_FLAG_ADD_IF_NEW)
    ' --- 5. 准备要发送的数据 (POST Body) ---
    .局部变量 post_data, 文本型
    post_data = "username=testuser&password=testpass123"
    ' --- 6. 发送请求和数据 ---
    nResult = HttpSendRequest (hRequest, , 0, post_data, 取文本长度 (post_data))
    .(nResult = 0)
        信息框 ("HttpSendRequest 失败!", 0, , )
        InternetCloseHandle (hRequest)
        InternetCloseHandle (hConnect)
        InternetCloseHandle (hInternet)
        返回 ()
    .如果结束
    ' --- 7. 读取响应头,获取 Set-Cookie ---
    ' 在实际应用中,服务器可能不会在登录响应中直接设置 Cookie,或者设置在响应头中
    ' 这里我们用一个通用的方法来查找 "Set-Cookie"
    dwSize = 8192
    .循环判断首 (真)
        lpBuffer = 取空白文本 (dwSize)
        nResult = HttpQueryInfo (hRequest, 32, lpBuffer, dwSize, 0) ' HTTP_QUERY_SET_COOKIE
        .(nResult ≠ 0 且 到整数 (取中间文本 (lpBuffer, 1, 4)) > 0)
            ' 找到了 Set-Cookie 头
            sessionCookie = lpBuffer
            跳出循环 ()
        .否则
            .( GetLastError () () 122) ' ERROR_INSUFFICIENT_BUFFER
                dwSize = dwSize * 2
            .否则
                ' 没有找到 Set-Cookie 头
                跳出循环 ()
            .如果结束
        .如果结束
    .循环判断尾 ()
    ' --- 8. 关闭登录请求句柄 ---
    InternetCloseHandle (hRequest)
    ' --- 9. 如果获取到了 Cookie,则用它来访问需要登录的页面 ---
    .(寻找 (sessionCookie, "session", , 假) > 0)
        信息框 ("成功获取到 Cookie: " + sessionCookie, 0, , )
        ' --- 10. 重新打开一个请求,访问需要登录的页面 ---
        hRequest = HttpOpenRequest (hConnect, "GET", "/get", , , , , 0)
        .(hRequest = 0)
            信息框 ("第二次 HttpOpenRequest 失败!", 0, , )
            跳到 (关闭句柄)
        .如果结束
        ' --- 11. 关键步骤:将获取到的 Cookie 添加到新请求的请求头中 ---
        .局部变量 cookieHeader, 文本型
        cookieHeader = "Cookie: " + sessionCookie
        HttpAddRequestHeaders (hRequest, cookieHeader, -1, HTTP_ADDREQ_FLAG_ADD_IF_NEW)
        ' --- 12. 发送第二次请求 ---
        nResult = HttpSendRequest (hRequest, , 0, , 0)
        .(nResult = 0)
            信息框 ("第二次 HttpSendRequest 失败!", 0, , )
            跳到 (关闭句柄)
        .如果结束
        ' --- 13. 读取并显示第二次请求的响应体 ---
        .局部变量 html, 文本型
        html = ""
        .循环判断首 (真)
            lpBuffer = 取空白文本 (1024)
            nResult = InternetReadFile (hRequest, lpBuffer, 1024, dwSize)
            .(nResult ≠ 0 且 dwSize > 0)
                html = html + 取中间文本 (lpBuffer, 1, dwSize)
            .否则
                跳出循环 ()
            .如果结束
        .循环判断尾 ()
        编辑框_结果.内容 = "成功访问需要登录的页面!"
        编辑框_结果.内容 = 编辑框_结果.内容 + #换行符 + #换行符 + "返回的JSON内容:" + #换行符 + html
    .否则
        信息框 ("未能从登录响应中获取到 Cookie!", 0, , )
    .如果结束
    ' --- 14. 关闭所有句柄 ---
.标签 (关闭句柄)
    InternetCloseHandle (hRequest)
    InternetCloseHandle (hConnect)
    InternetCloseHandle (hInternet)
.结束子

代码解释:

  1. API 声明: 你需要在代码最上方(通常在 .版本 2 之后)声明所有用到的 API,为了简洁,我在这里省略了,但在实际使用时必须加上。
  2. 流程: 代码严格按照我们前面分析的流程:初始化 -> 连接 -> 打开请求 -> 发送登录数据 -> 读取响应头获取 Cookie -> 关闭旧请求 -> 打开新请求 -> 添加 Cookie 到新请求头 -> 发送新请求 -> 读取新响应体 -> 关闭所有句柄。
  3. HttpQueryInfo: 这是获取响应头的关键,参数 32 代表 HTTP_QUERY_SET_COOKIE,专门用来获取 Set-Cookie 响应头。
  4. HttpAddRequestHeaders: 这是添加请求头的关键,在第二次请求前,我们将 sessionCookie 包装成 Cookie: ... 的格式添加到请求头中。
  5. InternetReadFile: 循环读取响应体,直到读取完毕。

使用第三方易语言 HTTP 组件(最简单,功能强大)

如果你觉得 WinINet API 太复杂,也可以使用一些优秀的第三方 HTTP 组件,这些组件通常封装了 libcurl 或其他现代 HTTP 库,提供了更简洁的易语言接口。

特点:

  • 优点: 代码非常简洁,功能强大,支持异步请求、SSL、代理等高级特性。
  • 缺点: 需要额外下载和导入组件文件。

示例(使用一个名为 易-CURL 的虚构组件):

.版本 2
.程序集 窗口程序集_启动窗口
.支持库 dp1
.子 _按钮_使用第三方组件_被单击 ()
    .局部变量 http, 对象
    .局部变量 html, 文本型
    .局部变量 cookieJar, 文本型
    ' 创建一个HTTP对象
    http.创建 ("CURL_Easy.创建", , 假)
    ' 设置URL
    http.设置_选项 ("URL", "http://httpbin.org/post")
    ' 设置POST数据
    http.设置_选项 ("POSTFIELDS", "username=testuser&password=testpass123")
    ' 设置一个Cookie Jar文件,用于自动保存和加载Cookie
    cookieJar = 取运行目录 () + "\cookies.txt"
    http.设置_选项 ("COOKIEJAR", cookieJar)
    http.设置_选项 ("COOKIEFILE", cookieJar) ' 同时加载
    ' 执行请求
    html = http.执行 ()
    ' 显示登录结果
    编辑框_结果.内容 = "登录请求已发送,Cookie已保存到: " + cookieJar + #换行符 + #换行符 + "登录响应:" + #换行符 + html
    ' --- 现在我们来访问需要登录的页面 ---
    http.设置_选项 ("URL", "http://httpbin.org/get")
    ' 注意:这里我们不需要再手动设置Cookie,因为组件会自动从cookieJar中加载
    html = http.执行 ()
    ' 显示最终结果
    编辑框_结果.内容 = 编辑框_结果.内容 + #换行符 + #换行符 + "访问用户中心成功!响应内容:" + #换行符 + html
    ' 释放对象
    http.销毁 ()
.结束子

说明:

  • 这种方法使用了 COOKIEJARCOOKIEFILE 选项。COOKIEJAR 指定一个文件,当请求结束时,会把服务器设置的 Cookie 保存到这个文件里。COOKIEFILE 指定一个文件,在发起请求前,会从这个文件里读取 Cookie 并自动添加到请求头中。
  • 这是最“优雅”和“自动化”的解决方案,强烈推荐给不想与底层 API 打交道的开发者。

总结与建议

方法 优点 缺点 适用场景
网页访问插件 极其简单,代码少 功能弱,无法自动获取Cookie,只能手动添加 简单的GET请求,且Cookie已知或不变
WinINet API 功能强大,完全可控,Windows原生支持 代码复杂,需要处理底层细节 需要精细控制HTTP请求,是学习和专业开发的推荐选择
第三方组件 代码简洁,功能强大,高级特性支持好 需要额外依赖第三方文件 追求开发效率,需要处理复杂网络请求(如HTTPS、代理、异步)的首选

对于初学者,建议先从 方法一 了解基本概念。 对于希望深入掌握或进行复杂开发的用户,方法二 (WinINet API) 是必经之路。 对于追求效率的项目,强烈推荐寻找并使用一个可靠的 第三方 HTTP 组件