table of Contents
About the Rest method of uploading files using multipart/form-data in H5 or delphi
2. Steps to apply for cloud service:
2.1. First, apply for an account on the cloud service provider's platform
2.3. Apply for Service Signature Signature
2.4. Read service API access and code call instructions
3. Steps to prepare architecture and code:
3.1.1. Get the User ID of the account
3.2.1. Prepare all APIs to access common resources (variables)
2. About the principle of multipart/form-data
1. What is multipart/form-data
2. Why does multipart/form-data appear?
3. Solve the code logic of Rest application when delphi uses the TNetHttp system:
If you like it, just click like and favorite below, so that you can watch the next sharing:
About the Rest method of uploading files using multipart/form-data in H5 or delphi
1. Look at the official case first: CloudAPI cloud API test project of Amazon Amazon and Microsoft Azure
${YourDelphiInstallPath}\Samples\Object Pascal\Database\CloudAPI\CloudAPITest\CloudAPITest.dproj
1. Mainly involved units:
1.1. CloudRefactorUI.pas // ${YourDelphiInstallPath}\Samples\Object Pascal\Database\CloudAPI\CloudAPITest\ //: Cloud API test UI main interface unit file
1.1.2, CloudPopulator.pas // ${YourDelphiInstallPath}\Samples\Object Pascal\Database\CloudAPI\CloudAPITest\ //: Cloud API test unit file
1.1.3, Data.Cloud.AmazonAPI.pas // ${YourDelphiInstallPath}\source\data\cloud //: Delphi Cloud Data Cloud Computing's Amazon API is translated into a unit of pascal
1.1.4, Data.Cloud.CloudAPI.pas // ${YourDelphiInstallPath}\source\data\cloud //: delphi cloud data cloud computing public unit
2. Steps to apply for cloud service:
2.1. First, apply for an account on the cloud service provider's platform
2.1.1, get the User ID of the account
2.1.2. Get the AK of the account (the Json or XML key-value pair of the account): Account Key
2.1.2. Get the SK of the account (password Json or XML key-value pair): Secret Key
2.2. Apply for a description of the services provided by the cloud platform and its access parameters
2.2.1, foreigners seem to be called "Buckets" (the translation of tmd is called "buckets")
2.3. Apply for Service Signature Signature
2.3.1. Obtain the signature of the required service
2.4. Read service API access and code call instructions
2.4.1, API access and code call instructions
3. Steps to prepare architecture and code:
3.1, architecture and design
3.1.1. Get the User ID of the account
Above, there are official codes, see for yourself! Below I use Alibaba Cloud Communication SMS Service API to explain as follows (the code part is taken from "Gao Yong's three-tier Rest server product"):
3.2. The basic steps of the code (you need to follow the detailed instructions of the cloud API service provided by the cloud service to implement the interface step by step)
3.2.1. Prepare all APIs to access common resources (variables)
3.2.1.1, baseURL : protocol SCHEME (http or https, most cloud services require https) + special reserved words Typical scheme'://' + host (host domain name or IP)
For example, Alibaba Cloud Communication baseURL: https://dysmsapi.aliyuncs.com
3.2.1.2, SortedParams: TArray<string>;:The parameter dictionary key-value pair array of the cloud service
For example, the parameter dictionary key-value pair array of Alibaba Cloud SMS Service ( some of the parameters in italics are listed below, and most of the cloud service API parameters are roughly the same for the rest of the parameters ):
Params := TDictionary<string, string>.Create;
Params.Add('AccessKeyId', AccessKeyId); //: AK (see the description of 2.1.2 above)
Params.Add('Timestamp', GetTimestamp ); //: time cut (different cloud service providers have different cloud services The format has special requirements) and the function GetTimestamp
Params.Add('Format','JSON'); //: request and response data format (different cloud service providers and different cloud services have special requirements for their data format: JSON or XML)
Params.Add('SignatureMethod','HMAC-SHA1'); //: signature encryption algorithm (different cloud service providers and different cloud services have special requirements for their algorithm)
Params.Add('SignatureNonce', THashMD5 .GetHashString(TGUID.NewGuid.ToString)); //: Use a different one-time encrypted signature string every time (different cloud service providers and different cloud services have special requirements for them: HashMD5 is commonly used)
Params.Add('SignatureVersion', '1.0'); //:Signature version
Params.Add('Action','SendSms'); //: Service specific function
Params.Add('Version', '2017-05-25'); //: Service version
Params.Add( 'RegionId','cn-hangzhou'); //: The service area
Params.Add('PhoneNumbers', PhoneNumbers); //: Other necessary parameters specific to the service
Params.Add('SignName', SignName); //: The signature of the applied service
Params.Add('TemplateCode', TemplateCode); //: Other necessary parameters unique to the service
Params.Add('TemplateParam', TemplateParam); //: Other necessary parameters unique to the service Preparation parameter
Params.Add ( 'OutId', '' );//: output parameters or JSON data
SortedParams := Params.keys.ToArray;
TArray.Sort<string>(SortedParams);
3.2.1.3. Construct the request query string to be signed
StringBuilder := TStringBuilder.Create;
//...The code is slightly
SortedQueryString := StringBuilder.ToString.Substring(1);
3.2.1.4. URL encoding the request string to be signed, removing or replacing special URL encoding characters
TNetEncoding.Url.Encode
3.2.2. Signature verification: Obtain the final required signature string Signature according to API requirements
Sign, the cloud server provides you to apply, and your client code must be known, but both the server and the client need to verify to ensure that the applicant (applicant organization) is accessing the cloud service under his account
Signature
3.2.3 Url of assembly service
Url := 'https://dysmsapi.aliyuncs.com/?Signature=' + Signature + '&' + SortedQueryString;
3.2.4, request service Url (Get or Post), get response response, parse the returned result of Json or XML data
HTTP.ContentType := 'application/x-www-form-urlencoded'; //: HTTP := TNetHTTPClient.Create(nil);
//: This HTTP.ContentType is the important setting assignment of important html header information that this article needs to talk about
Response := HTTP.Get(Url).ContentAsString(TEncoding.UTF8);
JsonObj := TJSONObject.ParseJSONValue(Response) as TJSONObject;
2. About the principle of multipart/form-data
1. What is multipart/form-data
It is one of the Enctype in HTML form, there are three types:
application/x-www-form-urlencoded ========== "corresponding to the parameter of THTTPClient.Post in delphi ASource: Mime type of TMultipartFormData: TMultipartFormData.Create or TMultipartFormData.AddField or TMultipartFormData.AddBytes or TMultipartFormData.AddStream application binary
If you want to send a large amount of binary data (non-ASCII), application/x-www-form-urlencoded is obviously inefficient, because it needs 3 characters to represent a non-ASCII character. Therefore, in this case, the "multipart/form-data" format should be used.
multipart/form-data ========== "Corresponding to the parameter of THTTPClient.Post in delphi ASource: Mime type of TMultipartFormData: Binary of TMultipartFormData.AddFile
Using "application/x-www-form-urlencoded" is inefficient for sending large amounts of binary data or text containing non-ASCII characters. "Multipart/form-data" should be used to submit forms containing files, non-ASCII data and binary data.
text-plain (ie: the default application/x-www-urlencoded) ========== "corresponding to the character string attached to the url link of Get in delphi or the content of the Body part of the Post webpage; or head Method to send header request.
By default, it is application/x-www-urlencoded. When the form uses a POST request, the data will be encoded in the body in x-www-urlencoded format for transmission, and if a GET request is sent, it will be sent after the url link . GET requests only support the ASCII character set, so if we want to send content with a larger character set, we should use POST requests.
2. Why does multipart/form-data appear?
HTML submission form data:
By default, it is application/x-www-urlencoded. When the form uses a POST request, the data will be encoded in the body in x-www-urlencoded for transmission, and if the GET request is attached, it is attached Send after the url link. GET requests only support the ASCII character set, so if we want to send content with a larger character set, we should use POST requests.
If you want to send a large amount of binary data (non-ASCII), application/x-www-form-urlencoded is obviously inefficient, because it needs 3 characters to represent a non-ASCII character. Therefore, in this case, the "multipart/form-data" format should be used.
Using "application/x-www-form-urlencoded" is inefficient for sending large amounts of binary data or text containing non-ASCII characters. "Multipart/form-data" should be used to submit forms containing files, non-ASCII data and binary data.
3. Solve the code logic of Rest application when delphi uses the TNetHttp system:
Delphi's Rest solution : " Delphi Restful: Four Ways of Client Implementation and Their Comparison ": https://blog.csdn.net/pulledup/article/details/104132753
System.Net.HttpClientComponent.pas ==========》 HTTP := TNetHTTPClient.Create(nil); ==========》
About the submission of multiple data objects TMultipartFormData of the form:
1. Multiple data objects of Post form
function Post(const AURL: string; const ASource: TMultipartFormData ; const AResponseContent: TStream = nil; const AHeaders: TNetHeaders = nil): IHTTPResponse ; overload;
2, Put multiple data objects of the form
function Put(const AURL: string; const ASource: TMultipartFormData ; const AResponseContent: TStream = nil; const AHeaders: TNetHeaders = nil): IHTTPResponse ; overload; ========= =》 IHTTPResponse: System.Net.HttpClient.pas
System.Net.HttpClient.pas ==========》 FHttpClient := THTTPClient.Create; FHttpClient.OnReceiveData := DoOnReceiveData; Result := THTTPClient(TURLSchemes.GetURLClientInstance('HTTP')); ==========》
System.Net.URLClient.pas ==========》 FSchemeClients.TryGetValue(AScheme.ToUpper, LClientClass); if LClientClass <> nil then Result := LClientClass.CreateInstance;TURLClient.CreateInstance: TURLClient; TURLClient.SetCustomHeaderValue(const Name, Value: string);
System.Net.Mime.pas ==========》
(
TMultipartFormData = class (TObject) //: See the public public properties and methods of the class for details
TMimeTypes = class (TObject) //: See the public public properties and methods of the class for details =========== "HTTP.ContentType :='MimeType type value';
TAcceptValueListBase<T: TAcceptValueItem, constructor> = class (TObject) //: See the public public properties and methods of the class for details
THeaderValueList = class (TObject) //: See the public public properties and methods of the class for details
)
System.NetConsts.pas ==========" (constant, error message)
//: uses System.NetConsts;
const
DefaultUserAgent = 'Embarcadero URI Client/1.0'; // Do not translate
// Common Header Names
sUserAgent = 'User-Agent'; // Do not translate
sAccept = 'Accept'; // Do not translate
sAcceptCharset = 'Accept-Charset'; // Do not translate
sAcceptEncoding = 'Accept-Encoding'; // Do not translate
sAcceptLanguage = 'Accept-Language'; // Do not translate
sAcceptRanges = 'Accept-Ranges'; // Do not translate
sContentEncoding = 'Content-Encoding'; // Do not translate
sContentLanguage = 'Content-Language'; // Do not translate
sContentLength = 'Content-Length'; // Do not translate
sContentType = 'Content-Type'; // Do not translate
sLastModified = 'Last-Modified'; // Do not translate
sContentDisposition = 'Content-Disposition'; // Do not translate
sLocation = 'Location'; // Do not translate
sSetCookie = 'Set-Cookie'; // Do not translate
sCookie = 'Cookie'; // Do not translate
sRange = 'Range'; // Do not translate
sXMethodOverride = 'x-method-override'; // Do not translate
sWWWAuthenticate = 'WWW-Authenticate'; // Do not translate
sProxyAuthenticate = 'Proxy-Authenticate'; // Do not translate
sAuthorization = 'Authorization'; // Do not translate
sProxyAuthorization = 'Proxy-Authorization'; // Do not translat
4. Refer to the blog post of netizens: "In- depth analysis of multipart/form-data " https://blog.csdn.net/wyn126/article/details/96451357
Related to this blog:
1. " Delphi Restful: Four Ways of Client Implementation and Their Comparison "
2. " RAD Studio 10.4.1 TEdgeBrowser and javascript interaction-Chromium-based Edge browser control usage 2 "
3. "Delphi Restful Interaction between Client JavaScript and Middleware Server"
If you like it, just click like and favorite below, so that you can watch the next sharing: