上传到跳过 Web 服务器
Upload to Skip Web Server
我正在尝试将 JSON 文件上传到 SKIP (getskip.com) 网络服务器,但出现套接字错误 10054。他们不太擅长提供示例,因为他们认为每个人都在使用 cUrl,但我们仍在使用 Delphi XE6 和 Indy。
这是他们提供的。
Java 使用 OK HTTP:
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
RequestBody body = RequestBody.create(mediaType, "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"path\"; filename=\"<<file_name>>\"\r\nContent-Type: application/vnd.novadigm.ext\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"data\"\r\n\r\n[{\"file_key\": \"path\", \"store_id\"::<<store_id>>}]\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");
Request request = new Request.Builder()
.url("https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json")
.post(body)
.addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.addHeader("Authorization", "Bearer <<api_user_token>>")
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("User-Agent", "PostmanRuntime/7.13.0")
.addHeader("Accept", "*/*")
.addHeader("Cache-Control", "no-cache")
.addHeader("Postman-Token", "de9932d2-bda0-4df6-8a9a-e2d4f74c2048,d59a9861-1a65-471a-8ada-6e025e985dca")
.addHeader("Host", "upload.goskip.com:8080")
.addHeader("accept-encoding", "gzip, deflate")
.addHeader("content-length", "407")
.addHeader("Connection", "keep-alive")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
Java 使用 Unirest:
HttpResponse<String> response = Unirest.post("https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json")
.header("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.header("Authorization", "Bearer <<api_user_token>>")
.header("Content-Type", "application/x-www-form-urlencoded")
.header("User-Agent", "PostmanRuntime/7.13.0")
.header("Accept", "*/*")
.header("Cache-Control", "no-cache")
.header("Postman-Token", "de9932d2-bda0-4df6-8a9a-e2d4f74c2048,d1ea454e-594c-4746-9de7-e813377ff095")
.header("Host", "upload.goskip.com:8080")
.header("accept-encoding", "gzip, deflate")
.header("content-length", "407")
.header("Connection", "keep-alive")
.header("cache-control", "no-cache")
.body("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"path\"; filename=\"<<file_name>>\"\r\nContent-Type: application/vnd.novadigm.ext\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"data\"\r\n\r\n[{\"file_key\": \"path\", \"store_id\":<<store_id>>}]\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")
.asString();
PHP 使用 HttpRequest:
<?php
$request = new HttpRequest();
$request->setUrl('https://upload.goskip.com:8080/v2/backoffice/files/pricebook');
$request->setMethod(HTTP_METH_POST);
$request->setQueryData(array(
'type' => 'json'
));
$request->setHeaders(array(
'cache-control' => 'no-cache',
'Connection' => 'keep-alive',
'content-length' => '407',
'accept-encoding' => 'gzip, deflate',
'Host' => 'upload.goskip.com:8080',
'Postman-Token' => 'de9932d2-bda0-4df6-8a9a-e2d4f74c2048,c7acbc0a-6450-43d1-b4ca-bc2a56cebc4e',
'Cache-Control' => 'no-cache',
'Accept' => '*/*',
'User-Agent' => 'PostmanRuntime/7.13.0',
'Content-Type' => 'application/x-www-form-urlencoded',
'Authorization' => 'Bearer <<api_user_token>>',
'content-type' => 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
));
$request->setBody('------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="path"; filename="<<file_name>>"
Content-Type: application/vnd.novadigm.ext
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"
[{"file_key": "path", "store_id"::<<store_id>>}]
------WebKitFormBoundary7MA4YWxkTrZu0gW--');
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
这是我在 Indy 中尝试过的。我将 JSON 文件粘贴到表格的备忘录中:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : TStringStream;
Response: String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
begin
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create;
IdHTTP1 := TIdHTTP.Create;
IdHTTP1.Request.CharSet := 'utf-8';
JsonToSend := TStringStream.Create(memolog.text, TEncoding.UTF8);
IdHTTP1.Request.ContentDisposition := 'form-data; name=[{"file_key":''' + memolog.text + ''', "store_id"::001}]------WebKitFormBoundary7MA4YWxkTrZu0gW--';
IdHTTP1.Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
IdHTTP1.Request.ContentType := 'multipart/form-data';
IdHTTP1.Request.Accept := '*/*';
IdHTTP1.Request.AcceptEncoding := 'gzip,deflate';
IdHTTP1.Request.ContentLength := -1;
IdHTTP1.Request.CacheControl := 'no-cache';
IdHTTP1.Request.Connection := 'keep-alive';
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.Host := 'upload.goskip.com:8080';
IdHTTP1.Request.CustomHeaders.Clear;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer eyJhbGc.......................';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := 'de9932d2-bda0-4df6-8a9a-e2d4f74c2048,d59a9861-1a65-471a-8ada-6e025e985dca';
IdHTTP1.ReadTimeout := 50000;
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
Response := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', JsonToSend);
HTTPPost := Response;
JsonToSend.Free;
IdHTTP1.Free;
end;
卷曲
Kim@KIMNEW MINGW64 ~
$ curl -F "file=@"C:/mydata/Items-114946.json -H "authorization:Bearer eyJ........................." https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json&store_id=001
[1] 13296
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Kim@KIMNEW MINGW64 ~
100 951k 100 53 100 951k 53 968k 0:00:01 --:--:-- 0:00:01 967k{"message":"#/data: null value where array expected"}
他们更新了所有端点,这是我得到的最新消息。
curl -X POST 'https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json' -H 'Authorization: Bearer <api_user_token>' -F path=@<path_to_first_file> -F path1=@<path_to_second_file> -F 'data=[{"file_key":"path","store_id":<store_id_for_first_file>},{"file_key":"path1","store_id":<store_id_for_second_file>}]'
你的 Delphi 代码全错了。
您将错误的 Content-Disposition
header 设置为错误的值。
您发布的 JSON 数据 as-is 根本没有将其包装在 MIME 中。
请勿手动设置 TIdHTTP.Request.AcceptEncoding
属性。您没有设置 TIdHTTP
来启用压缩支持,但您授予服务器发送压缩响应的权限,TIdHTTP
将无法为您解压缩。
使用 TIdHTTP
发送 multipart/form-data
请求的 正确 方法是使用重载的 Post()
方法,该方法采用 TIdMultipartFormDataStream
作为输入,像这样:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
PostData: TIdMultipartFormDataStream;
begin
JsonToSend := '[{"file_key": "path", "store_id": <<store_id>>}]';
IdHTTP1 := TIdHTTP.Create;
try
IdHTTP1.ReadTimeout := 50000;
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer ...';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := '...';
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
PostData := TIdMultipartFormDataStream.Create;
try
PostData.AddFormField('path', '', '', 'application/vnd.novadigm.ext').FileName := '<<file_name>>';
PostData.AddFormField('data', JsonToSend, 'utf-8', 'application/json').ContentTransfer := '8bit';
Result := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', PostData);
finally
PostData.Free;
end;
finally
IdHTTP1.Free;
end;
end;
如果服务器碰巧 TIdMultipartFormDataStream
格式化 MIME 数据的方式有问题(即,如果服务器拒绝 MIME Content-Type
and/or Content-Transfer-Encoding
header 由 TIdMultipartFormDataStream
为每个 MIME 字段生成,因为它还不符合 RFC 7578,HTML5 使用),您可以手动格式化 MIME 数据精确匹配 SKIP 的例子,像这样:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
PostData: TStringStream;
begin
JsonToSend := '[{"file_key": "path", "store_id": <<store_id>>}]';
IdHTTP1 := TIdHTTP.Create;
try
IdHTTP1.ReadTimeout := 50000;
IdHTTP1.Request.ContentType := 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW';
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer ...';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := '...';
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
PostData := TStringStream.Create(
'------WebKitFormBoundary7MA4YWxkTrZu0gW' + EOL +
'Content-Disposition: form-data; name="path"; filename="<<file_name>>"' + EOL +
'Content-Type: application/vnd.novadigm.ext' + EOL +
EOL +
EOL +
'------WebKitFormBoundary7MA4YWxkTrZu0gW' + EOL +
'Content-Disposition: form-data; name="data"' + EOL +
EOL +
JsonToSend + EOL +
'------WebKitFormBoundary7MA4YWxkTrZu0gW--',
TEncoding.UTF8
);
try
Result := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', PostData);
finally
PostData.Free;
end;
finally
IdHTTP1.Free;
end;
end;
UPDATE: 根据您提供的新curl 命令,您显示的原始示例与命令不匹配。试试这样的东西:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
PostData: TIdMultipartFormDataStream;
begin
JsonToSend := '[{"file_key": "path", "store_id": <<store_id>>}]';
IdHTTP1 := TIdHTTP.Create;
try
IdHTTP1.ReadTimeout := 50000;
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer ...';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := '...';
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
PostData := TIdMultipartFormDataStream.Create;
try
PostData.AddFile('path', '<<path_to_file>>').ContentTransfer := 'binary';
PostData.AddFormField('data', JsonToSend, 'utf-8', 'application/json').ContentTransfer := '8bit';
Result := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', PostData);
finally
PostData.Free;
end;
finally
IdHTTP1.Free;
end;
end;
或者:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
PostData: TMemoryStream;
FS: TIdReadFileExclusiveStream;
begin
JsonToSend := '[{"file_key": "path", "store_id": <<store_id>>}]';
IdHTTP1 := TIdHTTP.Create;
try
IdHTTP1.ReadTimeout := 50000;
IdHTTP1.Request.ContentType := 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW';
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer ...';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := '...';
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
PostData := TMemoryStream.Create;
try
WriteStringToStream(PostData, '------WebKitFormBoundary7MA4YWxkTrZu0gW' + EOL);
WriteStringToStream(PostData, 'Content-Disposition: form-data; name="path"; filename="<<file_name>>"' + EOL);
WriteStringToStream(PostData, 'Content-Type: ' + GetMIMETypeFromFile('<<file_name>>') + EOL);
WriteStringToStream(PostData, 'Content-Transfer-Encoding: binary' + EOL);
WriteStringToStream(PostData, EOL);
FS := TIdReadFileExclusiveStream.Create('<<path_to_file>>', fmOpenRead or fmShareDenyWrite);
try
PostData.CopyFrom(FS, 0);
finally
FS.Free;
end;
WriteStringToStream(PostData, EOL);
WriteStringToStream(PostData, '------WebKitFormBoundary7MA4YWxkTrZu0gW' + EOL);
WriteStringToStream(PostData, 'Content-Disposition: form-data; name="data"' + EOL);
WriteStringToStream(PostData, EOL);
WriteStringToStream(PostData, JsonToSend + EOL, IndyTextEncoding_UTF8);
WriteStringToStream(PostData, '------WebKitFormBoundary7MA4YWxkTrZu0gW--');
PostData.Position := 0;
Result := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', PostData);
finally
PostData.Free;
end;
finally
IdHTTP1.Free;
end;
end;
我正在尝试将 JSON 文件上传到 SKIP (getskip.com) 网络服务器,但出现套接字错误 10054。他们不太擅长提供示例,因为他们认为每个人都在使用 cUrl,但我们仍在使用 Delphi XE6 和 Indy。
这是他们提供的。
Java 使用 OK HTTP:
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
RequestBody body = RequestBody.create(mediaType, "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"path\"; filename=\"<<file_name>>\"\r\nContent-Type: application/vnd.novadigm.ext\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"data\"\r\n\r\n[{\"file_key\": \"path\", \"store_id\"::<<store_id>>}]\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");
Request request = new Request.Builder()
.url("https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json")
.post(body)
.addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.addHeader("Authorization", "Bearer <<api_user_token>>")
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("User-Agent", "PostmanRuntime/7.13.0")
.addHeader("Accept", "*/*")
.addHeader("Cache-Control", "no-cache")
.addHeader("Postman-Token", "de9932d2-bda0-4df6-8a9a-e2d4f74c2048,d59a9861-1a65-471a-8ada-6e025e985dca")
.addHeader("Host", "upload.goskip.com:8080")
.addHeader("accept-encoding", "gzip, deflate")
.addHeader("content-length", "407")
.addHeader("Connection", "keep-alive")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
Java 使用 Unirest:
HttpResponse<String> response = Unirest.post("https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json")
.header("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.header("Authorization", "Bearer <<api_user_token>>")
.header("Content-Type", "application/x-www-form-urlencoded")
.header("User-Agent", "PostmanRuntime/7.13.0")
.header("Accept", "*/*")
.header("Cache-Control", "no-cache")
.header("Postman-Token", "de9932d2-bda0-4df6-8a9a-e2d4f74c2048,d1ea454e-594c-4746-9de7-e813377ff095")
.header("Host", "upload.goskip.com:8080")
.header("accept-encoding", "gzip, deflate")
.header("content-length", "407")
.header("Connection", "keep-alive")
.header("cache-control", "no-cache")
.body("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"path\"; filename=\"<<file_name>>\"\r\nContent-Type: application/vnd.novadigm.ext\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"data\"\r\n\r\n[{\"file_key\": \"path\", \"store_id\":<<store_id>>}]\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")
.asString();
PHP 使用 HttpRequest:
<?php
$request = new HttpRequest();
$request->setUrl('https://upload.goskip.com:8080/v2/backoffice/files/pricebook');
$request->setMethod(HTTP_METH_POST);
$request->setQueryData(array(
'type' => 'json'
));
$request->setHeaders(array(
'cache-control' => 'no-cache',
'Connection' => 'keep-alive',
'content-length' => '407',
'accept-encoding' => 'gzip, deflate',
'Host' => 'upload.goskip.com:8080',
'Postman-Token' => 'de9932d2-bda0-4df6-8a9a-e2d4f74c2048,c7acbc0a-6450-43d1-b4ca-bc2a56cebc4e',
'Cache-Control' => 'no-cache',
'Accept' => '*/*',
'User-Agent' => 'PostmanRuntime/7.13.0',
'Content-Type' => 'application/x-www-form-urlencoded',
'Authorization' => 'Bearer <<api_user_token>>',
'content-type' => 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
));
$request->setBody('------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="path"; filename="<<file_name>>"
Content-Type: application/vnd.novadigm.ext
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"
[{"file_key": "path", "store_id"::<<store_id>>}]
------WebKitFormBoundary7MA4YWxkTrZu0gW--');
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
这是我在 Indy 中尝试过的。我将 JSON 文件粘贴到表格的备忘录中:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : TStringStream;
Response: String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
begin
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create;
IdHTTP1 := TIdHTTP.Create;
IdHTTP1.Request.CharSet := 'utf-8';
JsonToSend := TStringStream.Create(memolog.text, TEncoding.UTF8);
IdHTTP1.Request.ContentDisposition := 'form-data; name=[{"file_key":''' + memolog.text + ''', "store_id"::001}]------WebKitFormBoundary7MA4YWxkTrZu0gW--';
IdHTTP1.Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
IdHTTP1.Request.ContentType := 'multipart/form-data';
IdHTTP1.Request.Accept := '*/*';
IdHTTP1.Request.AcceptEncoding := 'gzip,deflate';
IdHTTP1.Request.ContentLength := -1;
IdHTTP1.Request.CacheControl := 'no-cache';
IdHTTP1.Request.Connection := 'keep-alive';
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.Host := 'upload.goskip.com:8080';
IdHTTP1.Request.CustomHeaders.Clear;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer eyJhbGc.......................';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := 'de9932d2-bda0-4df6-8a9a-e2d4f74c2048,d59a9861-1a65-471a-8ada-6e025e985dca';
IdHTTP1.ReadTimeout := 50000;
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
Response := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', JsonToSend);
HTTPPost := Response;
JsonToSend.Free;
IdHTTP1.Free;
end;
卷曲
Kim@KIMNEW MINGW64 ~
$ curl -F "file=@"C:/mydata/Items-114946.json -H "authorization:Bearer eyJ........................." https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json&store_id=001
[1] 13296
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
Kim@KIMNEW MINGW64 ~
100 951k 100 53 100 951k 53 968k 0:00:01 --:--:-- 0:00:01 967k{"message":"#/data: null value where array expected"}
他们更新了所有端点,这是我得到的最新消息。
curl -X POST 'https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json' -H 'Authorization: Bearer <api_user_token>' -F path=@<path_to_first_file> -F path1=@<path_to_second_file> -F 'data=[{"file_key":"path","store_id":<store_id_for_first_file>},{"file_key":"path1","store_id":<store_id_for_second_file>}]'
你的 Delphi 代码全错了。
您将错误的 Content-Disposition
header 设置为错误的值。
您发布的 JSON 数据 as-is 根本没有将其包装在 MIME 中。
请勿手动设置 TIdHTTP.Request.AcceptEncoding
属性。您没有设置 TIdHTTP
来启用压缩支持,但您授予服务器发送压缩响应的权限,TIdHTTP
将无法为您解压缩。
使用 TIdHTTP
发送 multipart/form-data
请求的 正确 方法是使用重载的 Post()
方法,该方法采用 TIdMultipartFormDataStream
作为输入,像这样:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
PostData: TIdMultipartFormDataStream;
begin
JsonToSend := '[{"file_key": "path", "store_id": <<store_id>>}]';
IdHTTP1 := TIdHTTP.Create;
try
IdHTTP1.ReadTimeout := 50000;
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer ...';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := '...';
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
PostData := TIdMultipartFormDataStream.Create;
try
PostData.AddFormField('path', '', '', 'application/vnd.novadigm.ext').FileName := '<<file_name>>';
PostData.AddFormField('data', JsonToSend, 'utf-8', 'application/json').ContentTransfer := '8bit';
Result := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', PostData);
finally
PostData.Free;
end;
finally
IdHTTP1.Free;
end;
end;
如果服务器碰巧 TIdMultipartFormDataStream
格式化 MIME 数据的方式有问题(即,如果服务器拒绝 MIME Content-Type
and/or Content-Transfer-Encoding
header 由 TIdMultipartFormDataStream
为每个 MIME 字段生成,因为它还不符合 RFC 7578,HTML5 使用),您可以手动格式化 MIME 数据精确匹配 SKIP 的例子,像这样:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
PostData: TStringStream;
begin
JsonToSend := '[{"file_key": "path", "store_id": <<store_id>>}]';
IdHTTP1 := TIdHTTP.Create;
try
IdHTTP1.ReadTimeout := 50000;
IdHTTP1.Request.ContentType := 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW';
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer ...';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := '...';
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
PostData := TStringStream.Create(
'------WebKitFormBoundary7MA4YWxkTrZu0gW' + EOL +
'Content-Disposition: form-data; name="path"; filename="<<file_name>>"' + EOL +
'Content-Type: application/vnd.novadigm.ext' + EOL +
EOL +
EOL +
'------WebKitFormBoundary7MA4YWxkTrZu0gW' + EOL +
'Content-Disposition: form-data; name="data"' + EOL +
EOL +
JsonToSend + EOL +
'------WebKitFormBoundary7MA4YWxkTrZu0gW--',
TEncoding.UTF8
);
try
Result := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', PostData);
finally
PostData.Free;
end;
finally
IdHTTP1.Free;
end;
end;
UPDATE: 根据您提供的新curl 命令,您显示的原始示例与命令不匹配。试试这样的东西:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
PostData: TIdMultipartFormDataStream;
begin
JsonToSend := '[{"file_key": "path", "store_id": <<store_id>>}]';
IdHTTP1 := TIdHTTP.Create;
try
IdHTTP1.ReadTimeout := 50000;
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer ...';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := '...';
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
PostData := TIdMultipartFormDataStream.Create;
try
PostData.AddFile('path', '<<path_to_file>>').ContentTransfer := 'binary';
PostData.AddFormField('data', JsonToSend, 'utf-8', 'application/json').ContentTransfer := '8bit';
Result := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', PostData);
finally
PostData.Free;
end;
finally
IdHTTP1.Free;
end;
end;
或者:
function TFormJsonWrite.HTTPPost: String;
var
JsonToSend : String;
IdHTTP1: TIdHTTP;
IdSSLIOHandlerSocketOpenSSL2: TIdSSLIOHandlerSocketOpenSSL;
PostData: TMemoryStream;
FS: TIdReadFileExclusiveStream;
begin
JsonToSend := '[{"file_key": "path", "store_id": <<store_id>>}]';
IdHTTP1 := TIdHTTP.Create;
try
IdHTTP1.ReadTimeout := 50000;
IdHTTP1.Request.ContentType := 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW';
IdHTTP1.Request.BasicAuthentication := false;
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'Bearer ...';
IdHTTP1.Request.CustomHeaders.Values['Postman-Token'] := '...';
IdSSLIOHandlerSocketOpenSSL2 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
IdSSLIOHandlerSocketOpenSSL2.SSLOptions.Method := sslvTLSv1_2;
IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL2;
PostData := TMemoryStream.Create;
try
WriteStringToStream(PostData, '------WebKitFormBoundary7MA4YWxkTrZu0gW' + EOL);
WriteStringToStream(PostData, 'Content-Disposition: form-data; name="path"; filename="<<file_name>>"' + EOL);
WriteStringToStream(PostData, 'Content-Type: ' + GetMIMETypeFromFile('<<file_name>>') + EOL);
WriteStringToStream(PostData, 'Content-Transfer-Encoding: binary' + EOL);
WriteStringToStream(PostData, EOL);
FS := TIdReadFileExclusiveStream.Create('<<path_to_file>>', fmOpenRead or fmShareDenyWrite);
try
PostData.CopyFrom(FS, 0);
finally
FS.Free;
end;
WriteStringToStream(PostData, EOL);
WriteStringToStream(PostData, '------WebKitFormBoundary7MA4YWxkTrZu0gW' + EOL);
WriteStringToStream(PostData, 'Content-Disposition: form-data; name="data"' + EOL);
WriteStringToStream(PostData, EOL);
WriteStringToStream(PostData, JsonToSend + EOL, IndyTextEncoding_UTF8);
WriteStringToStream(PostData, '------WebKitFormBoundary7MA4YWxkTrZu0gW--');
PostData.Position := 0;
Result := IdHTTP1.Post('https://upload.goskip.com:8080/v2/backoffice/files/pricebook?type=json', PostData);
finally
PostData.Free;
end;
finally
IdHTTP1.Free;
end;
end;