我正在嘗試TIdHttp.Put()用于 Microsoft 的Graph API,但無法使用Content-Range標頭。如果我使用的Ranges屬性,然后我得到關于丟失的錯誤Content-Range,如果我在使用此標題CustomHeaders屬性,然后我得到一個無效的錯誤Content-Range。
這是代碼:
sUploadSession := jsnUSession.Get('uploadUrl').JsonValue.Value;
Form1.htp2.Request.ContentType := 'application/octet-stream';
Form1.htp2.Request.ContentLength := iSize; // 3820753
Form1.htp2.Request.CustomHeaders.Clear;
//Form1.htp.Request.CustomHeaders.Add('Content-Length: ' IntToStr(iSize));
Form1.htp2.Request.CustomHeaders.Add('Content-Range: bytes 0-' IntToStr(iSize - 1) '/' IntToStr(iSize)); // 'Content-Range: bytes 0-3820750/3820751'
{with Form1.htp2.Request.Ranges.Add do
begin
StartPos := 0;
EndPos := iSize;
s := Text;
end; }
fs := TStringStream.Create('{' TEncoding.Default.GetString(TFile.ReadAllBytes(sFile)) '}');
bLog := True;
try
Form1.htp2.Put(sUploadSession, fs);
except
on E: EIdHTTPProtocolException do
Form1.RichEdit1.Lines.Add(E.Message #13#10 E.ErrorMessage);
end;
我使用該Ranges屬性時的訊息是:
HTTP/1.1 400 Bad Request
{"error":{"code":"MissingContentRangeHeader","message":"Content-Range header is required."}}
帶有Content-Rangein的訊息CustomHeaders是:
HTTP/1.1 400 Bad Request
{"error":{"code":"InvalidContentRangeHeader","message":"Invalid Content-Range header."}}
PUTIndy 中的命令是否與 HTTP 中的標準兼容,或者是否需要進行調整才能使其正常作業?
uj5u.com熱心網友回復:
在Range和Content-RangeHTTP頭是兩個完全不同的事情。請參閱Content-Range 和 Range 標頭之間的區別?
Content-Range用于指定包含Content-Range標題的同一訊息的正文中的位元組范圍。
所述Range報頭是用于請求的范圍內從所述服務器的位元組。回應訊息將通過它自己的 指示Content-Range在回應正文中發送的實際范圍。
所以,這就解釋了為什么Content-Range在使用該TIdHTTP.Ranges屬性時會出現“丟失”錯誤。該屬性根本不用于您使用它的目的。
至于使用TIdHTTP.Request.CustomHeaders屬性發送Content-Range標頭,這是正確的方法(從技術上講,TIdEntityHeaderInfo具有ContentRange...屬性,但它們目前僅用于 by TIdHTTP.Response,而不是 by TIdHTTP.Request-需要修復)。
您的自定義Content-Range標頭的問題在于服務器只是將其拒絕為糟糕的。這很可能意味著iSize您使用的值實際上與您實際發送的位元組數不匹配。
嘗試更像這樣的事情:
sUploadSession := jsnUSession.Get('uploadUrl').JsonValue.Value;
fs := TStringStream.Create('{' TEncoding.Default.GetString(TFile.ReadAllBytes(sFile)) '}');
try
bLog := True;
try
iSize := fs.Size; // <-- the TStringStream constructor internally converted the String to TBytes...
Form1.htp2.Request.ContentType := 'application/octet-stream';
Form1.htp2.Request.ContentLength := iSize;
Form1.htp2.Request.CustomHeaders.Clear;
Form1.htp2.Request.CustomHeaders.Add('Content-Range: bytes 0-' IntToStr(iSize - 1) '/' IntToStr(iSize));
Form1.htp2.Put(sUploadSession, fs);
except
on E: EIdHTTPProtocolException do
Form1.RichEdit1.Lines.Add(E.Message #13#10 E.ErrorMessage);
end;
finally
fs.Free;
end;
但是,沒有充分的理由將檔案讀入解碼的 UTF-16string以將其轉換回位元組進行傳輸,因此只需按原樣發送原始檔案位元組,例如:
sUploadSession := jsnUSession.Get('uploadUrl').JsonValue.Value;
fs := TFileStream.Create(sFile, fmOpenRead or fmShareDenyWrite);
try
bLog := True;
try
iSize := fs.Size;
Form1.htp2.Request.ContentType := 'application/octet-stream';
Form1.htp2.Request.ContentLength := iSize;
Form1.htp2.Request.CustomHeaders.Clear;
Form1.htp2.Request.CustomHeaders.Add('Content-Range: bytes 0-' IntToStr(iSize - 1) '/' IntToStr(iSize));
Form1.htp2.Put(sUploadSession, fs);
except
on E: EIdHTTPProtocolException do
Form1.RichEdit1.Lines.Add(E.Message #13#10 E.ErrorMessage);
end;
finally
fs.Free;
end;
或者:
sUploadSession := jsnUSession.Get('uploadUrl').JsonValue.Value;
fs := TBytesStream.Create(TFile.ReadAllBytes(sFile));
try
bLog := True;
try
iSize := fs.Size;
Form1.htp2.Request.ContentType := 'application/octet-stream';
Form1.htp2.Request.ContentLength := iSize;
Form1.htp2.Request.CustomHeaders.Clear;
Form1.htp2.Request.CustomHeaders.Add('Content-Range: bytes 0-' IntToStr(iSize - 1) '/' IntToStr(iSize));
Form1.htp2.Put(sUploadSession, fs);
except
on E: EIdHTTPProtocolException do
Form1.RichEdit1.Lines.Add(E.Message #13#10 E.ErrorMessage);
end;
finally
fs.Free;
end;
或者:
sUploadSession := jsnUSession.Get('uploadUrl').JsonValue.Value;
fs := TMemoryStream.Create;
try
bLog := True;
try
fs.LoadFromFile(sFile);
fs.Position := 0;
iSize := fs.Size;
Form1.htp2.Request.ContentType := 'application/octet-stream';
Form1.htp2.Request.ContentLength := iSize;
Form1.htp2.Request.CustomHeaders.Clear;
Form1.htp2.Request.CustomHeaders.Add('Content-Range: bytes 0-' IntToStr(iSize - 1) '/' IntToStr(iSize));
Form1.htp2.Put(sUploadSession, fs);
except
on E: EIdHTTPProtocolException do
Form1.RichEdit1.Lines.Add(E.Message #13#10 E.ErrorMessage);
end;
finally
fs.Free;
end;
無論哪種方式,請注意 Microsoft 建議在使用此PUTAPI時不要一次上傳超過 4MB 。您的示例檔案為 3.6MB,因此它只能容納在單個PUT請求中,但要知道對于較大的檔案,您必須將它們分成多個 4MB 上傳,注意NextExpectedRanges每個成功回應中的欄位。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/315590.html
標籤:德尔福 microsoft-graph-api 印地 idhttp
上一篇:Firedac將列名作為引數傳遞
下一篇:如何縮短有關標簽標題的重復代碼?
