0fn*_*fnt 3 powershell http-status-code-301 url-redirection powershell-v6.0
我在Linux上使用AppImage使用Powershell Core v6-beta.5。有没有办法找出301重定向的“新”位置?
Invoke-WebRequest -Method HEAD http://SomethingThatThrows301.com/ -MaximumRedirection 0引发错误(Response status code does not indicate success: 301 (Moved Permanently))。
虽然错误确实提到此举是301,但我仍然希望有一个适当的对象告诉我,以及新地址。
有办法吗?
注意:以下所有代码均可在所有受支持的平台上的Windows PowerShell和PowerShell Core中使用,默认情况下最多可进行50个重定向。
假如说:
使用以下内容:
[System.Net.HttpWebRequest]::Create('http://cnn.com').GetResponse().ResponseUri.AbsoluteUri
Run Code Online (Sandbox Code Playgroud)
这样会产生结果(请注意目标网址的显示方式www.):
http://www.cnn.com
Run Code Online (Sandbox Code Playgroud)
以下是高级便捷功能Get-UrlRedirection的源代码,该功能打包了功能,既提供了最终目标URL的解析,又提供了重定向URL链的枚举。
示例调用:
> Get-UrlRedirection http://cnn.com
http://www.cnn.com
> Get-UrlRedirection -Enumerate http://microsoft.com/about
http://microsoft.com/about
https://microsoft.com/about
https://www.microsoft.com/about
https://www.microsoft.com/about/
https://www.microsoft.com/about/default.aspx
https://www.microsoft.com/en-us/about/
Run Code Online (Sandbox Code Playgroud)
Function Get-UrlRedirection {
[CmdletBinding()]
Param (
[Parameter(Mandatory, ValueFromPipeline)] [Uri] $Url,
[switch] $Enumerate,
[int] $MaxRedirections = 50 # Use same default as [System.Net.HttpWebRequest]
)
process {
try {
if ($Enumerate) { # Enumerate the whole redirection chain, from input URL to ultimate target,
# assuming the max. count of redirects is not exceeded.
# We must walk the chain of redirections one by one.
# If we disallow redirections, .GetResponse() fails and we must examine
# the exception's .Response object to get the redirect target.
$nextUrl = $Url
$urls = @( $nextUrl.AbsoluteUri ) # Start with the input Uri
$ultimateFound = $false
# Note: We add an extra loop iteration so we can determine whether
# the ultimate target URL was reached or not.
foreach($i in 1..$($MaxRedirections+1)) {
Write-Verbose "Examining: $nextUrl"
$request = [System.Net.HttpWebRequest]::Create($nextUrl)
$request.AllowAutoRedirect = $False
try {
$response = $request.GetResponse()
# Note: In .NET *Core* the .GetResponse() for a redirected resource
# with .AllowAutoRedirect -eq $False throws an *exception*.
# We only get here on *Windows*, with the full .NET Framework.
# We either have the ultimate target URL, or a redirection
# whose target URL is reflected in .Headers['Location']
# !! Syntax `.Headers.Location` does NOT work.
$nextUrlStr = $response.Headers['Location']
$response.Close()
# If the ultimate target URL was reached (it was already
# recorded in the previous iteration), and if so, simply exit the loop.
if (-not $nextUrlStr) {
$ultimateFound = $true
break
}
} catch [System.Net.WebException] {
# The presence of a 'Location' header implies that the
# exception must have been triggered by a HTTP redirection
# status code (3xx).
# $_.Exception.Response.StatusCode contains the specific code
# (as an enumeration value that can be case to [int]), if needed.
# !! Syntax `.Headers.Location` does NOT work.
$nextUrlStr = try { $_.Exception.Response.Headers['Location'] } catch {}
# Not being able to get a target URL implies that an unexpected
# error ocurred: re-throw it.
if (-not $nextUrlStr) { Throw }
}
Write-Verbose "Raw target: $nextUrlStr"
if ($nextUrlStr -match '^https?:') { # absolute URL
$nextUrl = $prevUrl = [Uri] $nextUrlStr
} else { # URL without scheme and server component
$nextUrl = $prevUrl = [Uri] ($prevUrl.Scheme + '://' + $prevUrl.Authority + $nextUrlStr)
}
if ($i -le $MaxRedirections) { $urls += $nextUrl.AbsoluteUri }
}
# Output the array of URLs (chain of redirections) as a *single* object.
Write-Output -NoEnumerate $urls
if (-not $ultimateFound) { Write-Warning "Enumeration of $Url redirections ended before reaching the ultimate target." }
} else { # Resolve just to the ultimate target,
# assuming the max. count of redirects is not exceeded.
# Note that .AllowAutoRedirect defaults to $True.
# This will fail, if there are more redirections than the specified
# or default maximum.
$request = [System.Net.HttpWebRequest]::Create($Url)
if ($PSBoundParameters.ContainsKey('MaxRedirections')) {
$request.MaximumAutomaticRedirections = $MaxRedirections
}
$response = $request.GetResponse()
# Output the ultimate target URL.
# If no redirection was involved, this is the same as the input URL.
$response.ResponseUri.AbsoluteUri
$response.Close()
}
} catch {
Write-Error $_ # Report the exception as a non-terminating error.
}
} # process
}
Run Code Online (Sandbox Code Playgroud)
为了专注于代码,我省略了上面基于注释的帮助。这就是-只需将其直接粘贴在函数定义上方即可:
[System.Net.HttpWebRequest]::Create('http://cnn.com').GetResponse().ResponseUri.AbsoluteUri
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2487 次 |
| 最近记录: |