VC++ 获取跳转后的url函数实现及相关资料

// 函数名称:GetHttpRedirectUrl
// 函数功能:根据源url获取服务器的跳转后的url,所有函数均为WinInet API
// 输入参数:strSrcUrl 源url   strDesUrl 跳转后的url
// 函数说明:例如:
//      源url:down.mumayi.com/1  实际上为mumayi://down.mumayi.com/1,我们网站支持自己的协议
//      跳转后的url:http://apkb.mumayi.com/2013/04/03/30/303163/mumayidianzishichangMumayiMarket_V1.6.8.6_mumayi_f5c77.apk
// 补    充:因为赶时间,函数写的比较粗糙,考虑的不周全,好多地方需要完善
//      调用该函数前,应确保strSrcUrl为跳转地址,因为该函数内部没有判断其是否为跳转地址
// 时    间:2013_4_9
BOOL CMuMaYiInstallerApp::GetHttpRedirectUrl(CString strSrcUrl, CString strDesUrl)
{
 HINTERNET hOpen;
 HINTERNET hConnect;
 HINTERNET hRequest;
 int nState = strSrcUrl.Find(".com");
 CString strObjectName = strSrcUrl.Mid(nState+4); // 获取对象(文件)地址
 CString strAgentName("");
 strAgentName.Format("KDWS_%s", this);

 // 创建位于根部的HInternet句柄,然后才能通过其进一步建立HTTP、FTP的连接
 hOpen = InternetOpen(strAgentName, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
 if ( NULL == hOpen )
  return FALSE;
 
 // 创建一个指定的连接,它将通过传递给它的参数为指定的站点初始化HTTP、FTP连接
 hConnect = InternetConnect(hOpen,
       "down.mumayi.com", // 域名(服务器地址)
       80,     // 服务器端口
       NULL, NULL,
       INTERNET_SERVICE_HTTP,
       0,0 );
 if ( NULL == hConnect)
 {
  InternetCloseHandle(hOpen);
  return FALSE;
 }

 DWORD dwFlags = 
 INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_RAW_DATA|INTERNET_FLAG_RELOAD|        
 INTERNET_FLAG_NO_AUTO_REDIRECT|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_PRAGMA_NOCACHE; 

 // 创建一个HTTP请求
 hRequest = HttpOpenRequest(hConnect, NULL, strObjectName, NULL, NULL, NULL, dwFlags,  NULL);
 if ( !hRequest )
 {
  InternetCloseHandle(hConnect);
  InternetCloseHandle(hOpen);
  return FALSE;
 }

 CString strHeaders("Accept: */*\r\nContent-Type: application/x-www-form-urlencoded");

 // 说白了就是给hRequest添加发送前所需的头
 BOOL bResult = HttpAddRequestHeaders(hRequest, strHeaders, strHeaders.GetLength(), HTTP_ADDREQ_FLAG_ADD);
 if (!bResult)
 {
  InternetCloseHandle(hConnect);
  InternetCloseHandle(hOpen);
  InternetCloseHandle(hRequest);
  return FALSE;
 }

 // INTERNET_OPTION_SEND_TIMEOUT 设置,发送请求和连接时的超时时间
 // INTERNET_OPTION_RECEIVE_TIMEOUT 设置,接收请求和连接时的超时时间
 unsigned long lms = 15*1000;
 InternetSetOption(hOpen, INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT, &lms, sizeof(lms));
 InternetSetOption(hOpen, INTERNET_OPTION_SEND_TIMEOUT, &lms, sizeof(lms));

 // 发送一个不带任何数据的HTTP请求,以此来获得跳转后的url
 if ( HttpSendRequest(hRequest, NULL, 0, NULL, 0) )
 {
  //GetStatusCode(hRequest);
  TCHAR szBuffer[INTERNET_MAX_URL_LENGTH] = {0};
  DWORD dwLen = sizeof(szBuffer);

  // 获取HTTP请求信息(HTTP_QUERY_LOCATION获取的绝对URL在Location应答头)
  BOOL bRet = HttpQueryInfo(hRequest, HTTP_QUERY_LOCATION, szBuffer, &dwLen, NULL);
  strDesUrl = szBuffer;
 }
 HttpEndRequest(hRequest, NULL, NULL, NULL);
 InternetCloseHandle(hConnect);
    InternetCloseHandle(hOpen);
 InternetCloseHandle(hRequest);
   
 return TRUE;
}

 

 

下面整理一下WinInet API相关资料(摘自-百度知道)

 

MSDN:

Microsoft provides many APIs for programming both client and server applications. Many new applications are being written for the Internet, and as technologies, browser capabilities, and security options change, new types of applications will be written. Browsers run on client computers, providing access to the World Wide Web and displaying HTML pages that contain text, graphics, ActiveX controls, and documents. Servers provide FTP, HTTP, and gopher services, and run server extension applications using CGI and ISAPI. Your custom application can retrieve information and provide data on the Internet....

 

 

WinInet 概述

⊙ Hinternet 句柄的层次关系

⊙ HTTP 函数层次关系

⊙ 典型的 HTTP 客户端程序的处理流程

1、普通 WinInet 处理函数

InternetOpen 初始化 WinInet.dll

InternetOpenUrl 打开 Url,读取数据

⊙ InternetAttemptConnect 尝试建立到 Internet 的连接

⊙ InternetConnect 建立 Internet 的连接

⊙ InternetCheckConnection 检查 Internet 的连接是否能够建立

⊙ InternetSetOption 设置一个 Internet 选项

⊙ InternetSetStausCallback 安装一个回调函数,供 API 函数调用

⊙ InternetQueryOption 查询在一个指定句柄上的 Internet 选项

⊙ InternetQueryDataAvailable 查询可用数据的数量

⊙ InternetReadFile(Ex) 从一个打开的句柄读取数据

⊙ InternetFindNextFile 继续文件搜寻

⊙ InetrnetSetFilePointer 为 InternetReadFile 设置一个文件位置

⊙ InternetWriteFile 将数据写到一个打开的 Internet 文件

⊙ InternetLockRequestFile 允许用户为正在使用的文件加锁

⊙ InternetUnlockRequestFile 解锁被锁定的文件

⊙ InternetTimeFromSystemTime 根据指定的 RFC 格式格式化日期和时间

⊙ InternetTimeToSystemTime 将一个 HTTP 时间/日期字串格式化为 SystemTime 结构对象

⊙ InternetConfirmZoneCrossing 检查在安全 URL 和非安全 URL 间的变化

⊙ InternetCloseHandle 关闭一个单一的 Internet 句柄

⊙ InternetErrorDlg 显示错误信息对话框

⊙ InternetGetLastResponesInfo 获取最近发送的 API函数的错误

2、HTTP 处理函数

⊙ HttpOpenRequest 打开一个 HTTP 请求的句柄

⊙ HttpSendRequert(Ex) 向 HTTP 服务器发送指定的请求

⊙ HttpQueryInfo 查询有关一次 HTTP 请求的信息

⊙ HttpEndRequest 结束一个 HTTP 请求

⊙ HttpAddRequestHeaders 添加一个或多个 HTTP 请求报头到 HTTP请求句柄

3、FTP 处理函数

⊙ FtpCreateDirectory 在 Ftp 服务器新建一个目录

⊙ FtpDelectFile 删除存储在 Ftp 服务器上的文件

⊙ FtpFindFirstFile 查找给定 Ftp 会话中的指定目录

⊙ FtpGetCurrentDirectory 为指定 Ftp 会话获取当前目录

⊙ FtpGetFile 从 Ftp 服务器下载文件

⊙ FtpOpenFile 访问一个远程文件以对其进行读写

⊙ FtpPutFile 向 Ftp 服务器上传文件

⊙ FtpRemoveDirectory 在 Ftp 服务器删除指定的文件

⊙ FtpRenameFile 为 Ftp 服务器上的指定文件改名

⊙ FtpSetCurrentDirectory 更改在 Ftp 服务器上正在使用的目录

 

 

WinInet 层关系

1、WinInet 是一个网络编程接口,包含了 Internet 底层协议 HTTP,FTP。

2、借助 WinInet 接口,可不必去了解 Winsock、TCP/IP 和特定 Internet 协议

的细节就可以编写出高水平的 Internet 客户端程序。

3、WinInet 为 HTTP、FTP 提供了统一的函数集,也就是 Win32 API 接口。

4、WinInet 简化了 HTTP、FTP 协议的编程,可轻松地将 Internet 集成到应用程序中。

Hinternet 句柄的层次关系

1、首先通过 InternetOpen 函数创建位于根部的 Hinternet 句柄,

然后才能通过其进一步建立 HTTP、FTP 的连接。

2、使用 InternetConnect 函数创建一个指定的连接,它将通过传递给它的参数为指定的

站点初始化 HTTP、FTP 连接并创建一个从根句柄分支出去的 Hinernet 句柄。

3、HttpOpenRequest 和 FtpOpenFile、FtpFindFirstFile等函数将使用 InternetConnect

所创建的句柄以建立到指定站点的连接。

HTTP 函数层次关系

1、对于 WWW 服务器提供的资源可以直接通过 InternetOpenUrl 或是 HTTP 函数对潜在

的协议进行处理来访问。

2、由于 HTTP 协议是在不断发展的,当这些底层协议被更新后也将影响这些 HTTP 函数行为

3、InternetOpen、InternetConnect、HttpOpenRequest 将返回 Hinternet 句柄,而

HttpAddRequestHeaders、HttpQueryInfo、HttpSendRequest、HttpSendRequestEx、

InternetErrorDlg 将使用它们所依靠的这些函数创建的 Hinternet句柄。

FTP 函数层次关系

1、FTP 函数需要请求得到特定类型的 Hinternet句柄才能正常工作,这些句柄的创建

必须按一定次序来进行:

1、首先使用 InternetOpen 创建根句柄,然后才能通过 InternetConnect 创建一个

FTP连接句柄

2、该图展示了依赖于 InternetConnect 所返回FTP 连接句柄的 FTP函数之间的层次关系。

典型的 HTTP 客户端程序的处理流程

1、目的:开始 HTTP会话,建立 HTTP 连接

方法:InetrnetOpen、

InternetAttemptConnect

InternetConnect

结果:初始化 WinInet.dll 并联接服务器,返回相应的句柄

2、目的:创建一个 HTTP请求

方法:HttpOpenRequest

结果:

3、目的:发送一个 HTTP请示

方法:HttpAddRequestHeaders

HttpSendRequert(Ex)

结果:

4、目的:读文件

方法:InternetReadFile(Ex)

结果:使用你提供的缓冲读指定的字节

5、目的:获取 HTTP请求信息

方法:HttpQueryInfo

结果:从服务器获取 HTTP 请求头信息

6、目的:异常处理

方法:InternetGetLastResponesInfo

InternetErrorDlg

结果:处理所有普通的异常类型

7、目的:结束 HTTP 会话

方法:HttpEndRequest、

InternetCloseHandle

结果:自动清除打开的句柄的连接

InetrnetOpen 初始化

1、声明:

function InternetOpen(lpszAgent: PChar;

dwAccessType: DWORD;

lpszProxy,

lpszProxyBypass:PChar;

dwFlags: DWORD): HINTERNET; stdcall;

2、参数:

1、lpszAgent 应用程序名,可以自定义

2、dwAccessType 存取类型,可以是:

1、INTERNET_OPEN_TYPE_PRECONFIG =0 使用 IE 中的连接设置

2、INTERNET_OPEN_TYPE_DIRECT =1 直接连接到服务器

3、INTERNET_OPEN_TYPE_PROXY =3 通过代理服务器进行连接

为 3 时需指定代理服务器地址

3、lpszProxy CERN 代理服务器地址,一般设置为 null;

4、lpszProxyBypass 代理服务器地址;

5、dwFlags 标记,一般设置为 0,可以是:

1、INTERNET_FLAG_DONT_CACHE 不在缓存中保存取得的内容

2、INTERNET_FLAG_OFFLINE 脱机方式

InternetOpenUrl 打开 Url,读取数据

1、声明:

function InternetOpenUrl(hInet: HINTERNET;

lpszUrl: PChar;

lpszHeaders: PChar;

dwHeadersLength: DWORD;

dwFlags: DWORD;

dwContext: DWORD): HINTERNET; stdcall;

2、参数:

1、hInet 由 InternetOpen 返回的句柄

2、lpszUrl 文件 Url 地址,以 http:,ftp:打头的 Url 地址;

3、lpszHeaders 发送到服务器的数据头;

4、dwHeadersLength 发送到服务器的数据头长度

5、dwFlags 标记,可以是:

1、INTERNET_FLAG_RELOAD 强制重读数据

2、INTERNET_FLAG_DONT_CACHE 不保存到缓存

3、INTERNET_FLAG_TRANSFER_ASCII 使用文本数据

4、INTERNET_FLAG_TRANSFER_BINARY 使用二进制数据

6、dwContext 上下文标记,如果使用回调功能时这个值将传送给回调函数

Internet 的连接

1、声明:

function InternetConnect(hInet: HINTERNET;

lpszServerName: PChar;

nServerPort: INTERNET_PORT;

lpszUsername: PChar;

lpszPassword: PChar;

dwService: DWORD;

dwFlags: DWORD;

dwContext: DWORD): HINTERNET; stdcall;

2、参数:

1、hInet 由 InternetOpen 返回的句柄

2、lpszServerName 服务器的地址

HTTP 地址必须为服务器名作InternetOpenUrl 语法分析

3、nServerPort HTTP协议端口号(缺省80)

4、lpszUsername 用户名

5、lpszPassword 用户密码

6、dwService 决定服务类型 HTTP,FTP,可以是:

1、INTERNET_SERVICE_FTP = 1; 连接到一个 FTP 服务器上

2、INTERNET_SERVICE_HTTP = 3; 连接到一个 HTTP 服务器上

7、dwFlags

8、dwContext

HttpOpenRequest

1、声明:

function HttpOpenRequest(hConnect: HINTERNET;

lpszVerb: PChar;

lpszObjectName: PChar;

lpszVersion: PChar;

lpszReferrer: PChar;

lplpszAcceptTypes: PLPSTR;

dwFlags: DWORD;

dwContext: DWORD): HINTERNET; stdcall;

2、参数:

1、hConnect InternetConnect句柄

2、lpszVerb 命令字,如果为 NULL,使用缺省值“GET”

3、lpszObjectName 命令对象,通常是一个文件名、可执行文件或是一个搜索列表

4、lpszVersion HTTP版本,如果为空,将使用“HTTP/1.0”

5、lpszReferrer 一个网址,可以为空

6、lplpszAcceptTypes中 程序接收的文件类型列表。把空值传给该函数即通知了服务器只有文本文件可以被接收

'application/octet-stream'

7、dwFlags 标志 使用 or 连接标志

1、INTERNET_FLAG_NO_CACHE_WRITE 标志不缓冲写

2、INTERNET_FLAG_KEEP_CONNECTION 保持连接

3、INTERNET_FLAG_SECURE { use PCT/SSL if applicable (HTTP) }

{ Security Ignore Flags, Allow HttpOpenRequest to overide

Secure Channel (SSL/PCT) failures of the following types. }

4、INTERNET_FLAG_IGNORE_CERT_CN_INVALID { bad common name in X509 Cert. }

5、INTERNET_FLAG_IGNORE_CERT_DATE_INVALID { expired X509 Cert. }

8、dwContext Integer(Self)?

向 HTTP 服务器发送指定的请求

1、声明:

function HttpSendRequest(hRequest: HINTERNET;

lpszHeaders: PChar;

dwHeadersLength: DWORD;

lpOptional: Pointer;

dwOptionalLength: DWORD): BOOL; stdcall;

2、参数:

1、hRequest HttpOpenRequest句柄

2、lpszHeaders 服务请求的数据头

3、dwHeadersLength 服务请求的数据头的长度

4、lpOptional 紧路在标题后任意数据的地址,此参数一般用于 POST 和 PUT 操作

5、dwOptionalLength 数据的长度

InternetSetOption 设置一个 Internet 选项

1、声明

function InternetSetOption(hInet: HINTERNET;

dwOption: DWORD;

lpBuffer: Pointer;

dwBufferLength: DWORD): BOOL; stdcall;

2、参数:

1、hInet 句柄

2、dwOption Internet 选项,可以是:

INTERNET_OPTION_SEND_TIMEOUT 设置,发送请求和连接时的超时时间

INTERNET_OPTION_RECEIVE_TIMEOUT 设置,接收请求和连接时的超时间间

3、lpBuffer 值

4、dwBufferLength 值大小

【完】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如果你想在Python中获取跳转后的url,可以使用requests库中的history属性。这个属性返回一个列表,其中包含所有请求的响应,包括重定向的响应。你可以通过查看最后一个响应的url获取跳转后的url。 以下是一个示例代码: ```python import requests response = requests.get('http://www.example.com') final_url = response.history[-1].url if response.history else response.url print(final_url) ``` 这个示例代码首先发送一个GET请求到'http://www.example.com',然后获取最终的url并打印出来。如果有重定向,它将会打印最后一个响应的url。否则,它将打印原始请求的url。 ### 回答2: 要获取跳转后的URL,我们可以使用编程语言中的一些技术来实现。以下是一种获取跳转后的URL的常用方法: 1. 使用HTTP库:使用像Python的Requests库这样的HTTP库进行网络请求,可以自动处理重定向并返回最终的URL。可以使用get方法来发送请求,并在返回的响应中查找URL。 例如,在Python中可以使用如下代码获取跳转后的URL: ```python import requests response = requests.get('http://example.com') redirect_url = response.url print(redirect_url) ``` 2. 分析响应头:HTTP响应头中的Location字段包含了重定向后的URL。我们可以在发送HTTP请求后,检查响应头中是否包含Location字段,并获取其中的URL。 例如,在JavaScript中可以使用如下代码获取跳转后的URL: ```javascript fetch('http://example.com') .then(response => { const redirectUrl = response.headers.get('Location'); console.log(redirectUrl); }); ``` 3. 使用网络调试工具:网络调试工具(如Chrome浏览器的开发者工具)可以捕获浏览器发送和接收的HTTP请求和响应。通过查看请求和响应的详细信息,我们可以找到跳转后的URL。 这些方法都可以帮助我们获取跳转后的URL。具体选择哪种方法取决于你在使用的编程语言或工具,以及实际需求和情况。 ### 回答3: 要获取跳转后的URL,可以通过编程语言中的HTTP请求库来实现。以下是使用Python语言中的requests库获取跳转后的URL的示例代码: ```python import requests def get_redirected_url(url): try: response = requests.get(url, allow_redirects=False) redirected_url = response.headers['Location'] return redirected_url except: return None # 示例调用 url = "https://example.com" redirected_url = get_redirected_url(url) if redirected_url: print("跳转后的URL是:", redirected_url) else: print("无法获取跳转后的URL") ``` 在这个示例中,我们首先导入requests库。然后定义了一个名为`get_redirected_url()`的函数,它接受一个URL作为参数。在函数体中,我们使用`requests.get()`方法发送一个HTTP GET请求,并通过将`allow_redirects=False`作为参数,禁止requests自动进行重定向。 接下来,我们通过检查response的headers字典中的'Location'键来获取重定向的URL。如果没有重定向,headers字典中就不会有'Location'键,并且我们将返回None。 最后,我们使用示例URL调用`get_redirected_url()`函数,并根据返回的结果输出跳转后的URL或相应的错误消息。 这个函数可以用于获取各种网页、API或任何可通过URL访问的资源的跳转后的URL

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值