Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 多部分表单POST对Google的意外响应_.net_Post_C++ Cli_Multipartform Data - Fatal编程技术网

.net 多部分表单POST对Google的意外响应

.net 多部分表单POST对Google的意外响应,.net,post,c++-cli,multipartform-data,.net,Post,C++ Cli,Multipartform Data,因此,我正在开发一个小应用程序,该程序目前将硬盘上的指定图像发布到谷歌的反向图像搜索并处理响应。问题是我得到的回应不是预期的。我已经尽我所能复制了POST请求的结构,但我一辈子都不明白为什么我没有得到预期的响应。我确实收到了200个响应代码,但HTML输出是某种Google错误(按图像搜索不可用。请在几个小时后重试)。我已经使用Fiddler来确定请求的结构,从我所知道的,从我的应用程序生成的请求实际上是相同的,除了缺少Cookie头(可能是它吗?)。如果是这样,我将如何创建cookie并将其插

因此,我正在开发一个小应用程序,该程序目前将硬盘上的指定图像发布到谷歌的反向图像搜索并处理响应。问题是我得到的回应不是预期的。我已经尽我所能复制了POST请求的结构,但我一辈子都不明白为什么我没有得到预期的响应。我确实收到了200个响应代码,但HTML输出是某种Google错误(按图像搜索不可用。请在几个小时后重试)。我已经使用Fiddler来确定请求的结构,从我所知道的,从我的应用程序生成的请求实际上是相同的,除了缺少Cookie头(可能是它吗?)。如果是这样,我将如何创建cookie并将其插入到请求中

这是我的密码: (注意:我确信它可以写得更加雄辩和高效(例如,使用StringBuilder),我已经硬编码了很多,但它应该足够好,可以暂时测试基本功能)

String^url=”https://www.google.com/searchbyimage/upload";
HttpWebRequest^request=(HttpWebRequest^)WebRequest::Create(url);
请求->方法=“POST”;
请求->用户代理=“Mozilla/5.0(Windows NT 6.1;WOW64;rv:16.0)Gecko/20100101 Firefox/16.0”;
请求->接受=“text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8”;
请求->标题[“接受语言”]=“en-US,en;q=0.5”;
请求->标题[“接受编码”]=“gzip,deflate”;
字符串^boundary=“------------------------------------23281168279961”;
请求->ContentType=“多部分/表单数据;边界=”+边界;
请求->引用=”https://www.google.com/imghp?hl=en&tab=wi";
字符串^header=boundary+“\n”;
标题+=“内容配置:表单数据;名称=\“图像\u url\”\n\n;
标题+=边界+“\n”;
标题+=“内容配置:表单数据;名称=\“编码图像\”文件名=\“2010-04-09-ec52529.png\”\n”;
header+=“内容类型:image/png\n\n”;
字符串^footer=“\n”+边界+“\n”;
页脚+=“内容配置:表单数据;名称=\“图像\内容\”\n\n;
页脚+=边界+“\n”;
页脚+=“内容处置:表单数据;名称=\”文件名\“\n\n”;
页脚+=边界+“\n”;
页脚+=“内容配置:表单数据;名称=\”num\“\n\n”;
页脚+=“10\n”;
页脚+=边界+“\n”;
页脚+=“内容处置:表单数据;名称=\“hl\”\n\n”;
页脚+=“en\n”;
页脚+=边界+“\n”;
页脚+=“内容处置:表单数据;名称=\”安全\“\n\n”;
页脚+=“关闭\n”;
页脚+=边界+“\n”;
页脚+=“内容处理:表单数据;名称=\“bih\”\n\n”;
页脚+=“578\n”;
页脚+=边界+“\n”;
页脚+=“内容处理:表单数据;名称=\“biw\”\n\n”;
页脚+=“1366\n”;
页脚+=边界+“--\n”;
数组^headerData=编码::ASCII->GetBytes(标头);
数组^imageData=文件::ReadAllBytes(旧图像);
数组^footerData=编码::ASCII->GetBytes(页脚);
请求->内容长度=标题数据->长度+图像数据->长度+页脚数据->长度;
Stream^reqStream=request->GetRequestStream();
请求流->写入(headerData,0,headerData->长度);
请求流->写入(imageData,0,imageData->长度);
请求流->写入(页脚数据,0,页脚数据->长度);
HttpWebResponse^response=(HttpWebResponse^)请求->获取响应();
StreamReader^reader=gcnew StreamReader(响应->GetResponseStream());
字符串^things=reader->ReadToEnd();

事实证明,谷歌在处理请求头时有点挑剔。我遇到了三个问题:

  • 图像以base64编码,用
    +
    替换为
    -
    /
    替换为
    .
  • 内容类型
    边界参数不能被引用
  • 内容配置
    必须引用名称参数
如果您使用的是C#,这里有一个替代
MultipartFormDataContent
,它可以处理这些怪癖,代码改编自:

要上传您的图像,请执行以下操作:

private static string FileToBase64(string imagePath)
{
    byte[] content = File.ReadAllBytes(imagePath);
    string base64 = Convert.ToBase64String(content).Replace('+', '-').Replace('/', '_');
    return base64;
}

public static void UploadImage(string imagePath)
{
    using (var client = new HttpClient())
    {
        var form = new MultipartFormDataContentCompat();
        form.Add(new StringContent(FileToBase64(imagePath)), "image_content");
        form.Add(new StringContent(Path.GetFileName(imagePath)), "filename");
        var response = client.PostAsync("https://images.google.com/searchbyimage/upload", form).Result;
        // Do whatever you want with the response
    }
}

事实证明,谷歌在处理请求头时有点挑剔。我遇到了三个问题:

  • 图像以base64编码,用
    +
    替换为
    -
    /
    替换为
    .
  • 内容类型
    边界参数不能被引用
  • 内容配置
    必须引用名称参数
如果您使用的是C#,这里有一个替代
MultipartFormDataContent
,它可以处理这些怪癖,代码改编自:

要上传您的图像,请执行以下操作:

private static string FileToBase64(string imagePath)
{
    byte[] content = File.ReadAllBytes(imagePath);
    string base64 = Convert.ToBase64String(content).Replace('+', '-').Replace('/', '_');
    return base64;
}

public static void UploadImage(string imagePath)
{
    using (var client = new HttpClient())
    {
        var form = new MultipartFormDataContentCompat();
        form.Add(new StringContent(FileToBase64(imagePath)), "image_content");
        form.Add(new StringContent(Path.GetFileName(imagePath)), "filename");
        var response = client.PostAsync("https://images.google.com/searchbyimage/upload", form).Result;
        // Do whatever you want with the response
    }
}

你的
Expect
标题怎么了?嗯,问得好。不知道为什么会这样,我的代码中没有这样的地方。而且,你有新行分隔你的行。它应该是Internet标准的行尾(
\r\n
)。我用\r\n替换了\r\n;同样的结果。我还想出了如何从中删除Expect头,但同样的结果。嗨!你能做到吗?我试图用无头浏览器做同样的事情,但是我得到了同样的错误。以防万一,如果我找到答案,我会添加一个答案。你的
Expect
标题怎么了?嗯,好问题。不知道为什么会这样,我的代码中没有这样的地方。而且,你有新行分隔你的行。它应该是Internet标准的行尾(
\r\n
)。我用\r\n替换了\r\n;同样的结果。我还想出了如何从中删除Expect头,但同样的结果。嗨!你能做到吗?我试图用无头浏览器做同样的事情,但是我得到了同样的错误。以防万一,如果我找到了,我会添加一个答案
private static string FileToBase64(string imagePath)
{
    byte[] content = File.ReadAllBytes(imagePath);
    string base64 = Convert.ToBase64String(content).Replace('+', '-').Replace('/', '_');
    return base64;
}

public static void UploadImage(string imagePath)
{
    using (var client = new HttpClient())
    {
        var form = new MultipartFormDataContentCompat();
        form.Add(new StringContent(FileToBase64(imagePath)), "image_content");
        form.Add(new StringContent(Path.GetFileName(imagePath)), "filename");
        var response = client.PostAsync("https://images.google.com/searchbyimage/upload", form).Result;
        // Do whatever you want with the response
    }
}