了解带有 Fiddler 输出的 Invoke-WebRequest 调用

了解带有 Fiddler 输出的 Invoke-WebRequest 调用

我正在尝试将 XML 配置文件上传到 Netgate 路由器,他们给您的页面是 php 表单。这是使用 GUI 进行的常规配置文件上传 - 当我使用 GUI 页面时,Fiddler 显示交换如下所示(我注意到表单数据是键入的,并且值是一个文件):

Fiddler - 使用 GUI

我尝试将其抛出到invoke-web请求中:

$RestoreArguments =  @{
    __csrf_magic=$LoopCsrfToken;
    #nopackages=$true;
    #donotbackuprrd=$true;
    donotbackuprrd='yes';
    #encrypt=$false;
    encrypt_password='';
    conffile=[xml](get-content $conffile);
    switch_safe_restore=$true;
    #decrypt=$true;
    decrypt_password=$LoopPW;
    restorearea=$RestoreArea;
    backuparea='';
    restore='Restore Configuration'
    }
$LoopResult = Invoke-WebRequest -timeoutsec 5 -WebSession $LoopSession -Uri "$Luri/diag_backup.php" -Method 'Post' -Body $RestoreArguments 

Fiddler 捕获了这一情况:

Fiddler-PS 尝试 1

我认为问题可能在于它如何获取内容,因此我像这样替换了 conffile 参数:

conffile=[xml](get-content $conffile);

但看到Fiddler捕获:

Fiddler-PS 尝试 2

所以现在我认为这是参数的类型,但不确定如何向页面提供它想要的内容。顺便说一句,代码中没有错误。感谢您的想法!

更新:conffile=[xml](get-content $conffile); 删除从到 的 类型转换后 conffile=get-item $conffile;

该值不显示为文件,而是显示为路径:

Fiddler-PS 尝试 3

更新2:

为了避免混淆,我尝试了这个代码......

$RestoreArguments =  @{
    __csrf_magic=$LoopCsrfToken
    donotbackuprrd='yes'
    encrypt_password=''
    conffile=get-item -path $conffile
    decrypt_password=''
    restorearea=$RestoreArea
    backuparea=''
    restore='Restore Configuration'
    }
$LoopResult = Invoke-WebRequest -TimeoutSec $Timeout -WebSession $LoopSession -Uri "$Luri/diag_backup.php" -Method 'POST' -Body $RestoreArguments 

还有这段代码……

$RestoreArguments =  @{
    __csrf_magic=$LoopCsrfToken;
    donotbackuprrd='yes';
    encrypt_password='';
    conffile=get-item -path $conffile;
    decrypt_password='';
    restorearea=$RestoreArea;
    backuparea='';
    restore='Restore Configuration'
    }
$LoopResult = Invoke-WebRequest -TimeoutSec $Timeout -WebSession $LoopSession -Uri "$Luri/diag_backup.php" -Method 'POST' -Body $RestoreArguments 

... 这两个实例实际上并未执行上传。在 Fiddler 中,它们产生以下输出:

在此处输入图片描述

答案1

理想的 HTTP POST 请求的内容类型是 multipart/form-data。您需要匹配它。并且 conffile 键值对的值必须正确编码。

看着示例 6:简化的 Multipart/Form-Data 提交并注意使用-Form参数而不是-Body参数。使用它,PS 负责对任何文件对象值进行编码([System.IO.FileInfo])。

$Uri = 'https://api.contoso.com/v2/profile'
$Form = @{
    firstName  = 'John'
    lastName   = 'Doe'
    email      = '[email protected]'
    avatar     = Get-Item -Path 'c:\Pictures\jdoe.png'
    birthday   = '1980-10-15'
    hobbies    = 'Hiking','Fishing','Jogging'
}
$Result = Invoke-WebRequest -Uri $Uri -Method Post -Form $Form

答案2

如果您要传递文件本身而不是文件的内容,则需要告诉 PowerShell 使用 获取文件Get-Item而不是使用 文件的内容Get-Content

当你指定时[xml],会告诉 PowerShell 返回的数据(Get-Content $conffile)是 XML 数据,并且 PowerShell 应该验证它。因此,你告诉 PowerShell 设置$RestoreArguments.conffile为 XML之内文件$conffile,而不是告诉它将 XML 文件 $conffile 发送到站点。

您的代码的其余部分看起来不错,但如果不将其实际传递到您正在使用的网站,我无法确定。您只需更新一行即可$RestoreArguments.conffile

conffile=[xml](get-content $conffile);

到:

confFile = Get-Item -Path $confFile;

请参阅此处以了解有关以下两者之间差异的更多信息获取项目获取内容

相关内容