gpt4 book ai didi

.net - 百分比编码的斜线 ("/") 在请求调度之前被解码

转载 作者:行者123 更新时间:2023-12-03 23:47:46 26 4
gpt4 key购买 nike

我有一个包含多个斜杠字符( / )作为文件名(不是 URL)的一部分的 URL。但是当我发送 http 请求时,百分比编码的 %2F被翻译成 /在请求分发之前,因此会生成错误的 URL。

如何在 PowerShell 中忽略百分比编码的值进行文字 http 请求?

使用的实际 URL (Chromium browser):

https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Win_x64%2F292817%2Fchrome-win32.zip?generation=1409504089694000&alt=media

我试过 Invoke-WebRequest 小命令:

Invoke-WebRequest -Uri $ChromeUrl -OutFile $FilePath -Verbose

VERBOSE: GET https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Win_x64/292817/chrome-win32.zip?generation=1409504089694000&alt=media with 0-byte payload1`

未发现错误。

也试过 WebClient DownloadFile 方法:
$wclient = New-Object System.Net.WebClient
$wclient.DownloadFile($ChromeUrl, $FilePath)

由于再次请求错误的 URL,返回 404。

解决方法 1(成功)

briantist 提供的基于反射的解决方法和 Tanuj Mathur两者都工作得很好。后一种:
$UrlFixSrc = @" 
using System;
using System.Reflection;

public static class URLFix
{
public static void ForceCanonicalPathAndQuery(Uri uri)
{
string paq = uri.PathAndQuery;
FieldInfo flagsFieldInfo = typeof(Uri).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic);
ulong flags = (ulong) flagsFieldInfo.GetValue(uri);
flags &= ~((ulong) 0x30);
flagsFieldInfo.SetValue(uri, flags);
}
}
"@

Add-Type -TypeDefinition $UrlFixSrc-Language CSharp
[URLFix]::ForceCanonicalPathAndQuery([URI]$ChromeUrl)

Invoke-WebRequest -Uri $ChromeUrl -OutFile $FilePath -Verbose

VERBOSE: GET https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Win_x64%2F292640%2Fchrome-win32.zip?generation=1409351584147000&alt=media

解决方法 2(成功)

更干净的解决方案(由 Tanuj Mathur 提供),但需要访问系统文件,是通过添加配置文件 %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe.config内容如下:
<?xml version="1.0" encoding="utf-8" ?> 
<configuration>
<uri>
<schemeSettings>
<add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
<add name="https" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
</schemeSettings>
</uri>
</configuration>

相应的修改必须在 powerhsell_ise.exe.config 中进行让它在 ISE 中工作。

解决方法 3(失败)

我以为是 System.URI 隐式转换调用的类构造函数问题,它转换转义值。尝试了重载变体 Uri ([String]uriString, [Boolean]dontEscape) .但是没有区别。有或没有 dontEscape 的结果相同争论。
$uri = new-object System.Uri($ChromeUrl, $true)
$uri | Format-List OriginalString, AbsoluteUri

OriginalString : https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Win_x64%2F292817%2Fchrome-win32.zip?generation=1409504089694000&alt=media
AbsoluteUri : https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Win_x64/292817/chrome-win32.zip?generation=1409504089694000&alt=media

解决方法 4(失败)

还试图通过将百分比字符替换为其百分比编码值 %25 来欺骗 URI 解析器。 .但后来它完全忽略了一切。
Invoke-WebRequest -Uri $ChromeUrl.Replace('%', '%25') -OutFile $DownloadPath -Verbose

VERBOSE: GET https://www.googleapis.com/download/storage/v1/b/chromium-browser-continuous/o/Win_x64%252F292817%252Fchrome-win32.zip?generation=1409504089694000&alt=media with 0-byte pa yload

解决方法 5(未实现)

我发现正确请求 URL 的唯一方法是通过 Internet Explorer 实例。
$ie = New-Object -ComObject InternetExplorer.Application                
$ie.Visible = $true
$ie.Silent = $false
$ie.Navigate2($ChromeUrl)

但是后来我不知道如何自动单击“另存为”按钮并将其保存到所需的路径。另外,即使实现了,我也不觉得这是一个好的解决方案。当 IE 已经运行或从系统中卸载时会发生什么?

最佳答案

在过去的几个小时里,我一直在玩弄你的代码,这真是太棒了。给定的代码及其变体在 Powershell ISE 中运行时全部通过,但在 Powershell 控制台上失败。
问题本身似乎是 Microsoft Connect here 上记录的问题。 .

有趣的是,根据用户 Glenn Block's answer在相关问题上,此错误已在 .NET Framework 4.5 中修复。
您可以通过运行命令 $PSVersionTable 检查您的 Powershell 使用的 .NET 框架的版本。 .只要CLRVersion值的格式为 4.0.30319.x,其中 x > 1700,则您正在运行框架的 v4.5。

我在我的机器上的 .NET 框架 4.5 上运行 Powershell v4.0,这解释了为什么 Powershell ISE 显示正确的行为,但我无法弄清楚为什么 Powershell 控制台没有。我验证了两者加载的 .NET 程序集,它们似乎是相同的。

就目前情况而言,我们有两个选择。
一种是使用反射并在 .Net 类上设置一个私有(private)字段来防止这种行为(如 this answer 中所述)。
另一种是使用 Microsoft Connect 问题中列出的解决方法。这涉及以下步骤:

  • 转到您的 Powershell 安装文件夹(这是我机器上的 "C:\Windows\System32\WindowsPowerShell\v1.0\")。这个文件夹应该有文件powershell.exe在里面。
  • 在此文件夹中创建一个新的文本文件,并将其命名为 powershell.exe.config
  • 在文本编辑器中打开此文件,并将以下文本粘贴到其中:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <uri>
    <schemeSettings>
    <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
    <add name="https" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
    </schemeSettings>
    </uri>
    </configuration>
  • 保存此文件。关闭所有正在运行的 Powershell 实例。
  • 启动一个新的 Powershell 实例。这将导致 Powershell 检测您创建的配置文件并对其进行解析。配置条目基本上告诉 .NET 库禁用 HTTP 和 HTTPS uri 的自动转义。
  • 运行你的脚本。您应该不再看到 Uris 的问题。
  • 关于.net - 百分比编码的斜线 ("/") 在请求调度之前被解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25596564/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com