How to Send a POST Request with a Specific Content-type Header Using HTTP_FETCH()
Description
The content type cannot be set when using HTTP_POST() to POST data to a server. If the server expects a different Content-type header, HTTP_FETCH() can be used instead.
When sending a request using HTTP_POST, you may receive content type errors such as the one shown below indicating the content sent did not meet expectations:
? response = body = <?xml version="1.0" encoding="UTF-8"?> <response success="false"> <messages> <message key="invalid-xml">Illegal Input. Input data must be an XML document.</message> </messages> </response>
HTTP_POST() is an Xbasic function for sending an HTTP POST requests. To make the function easy to use, HTTP_POST() does not allow full control over the request and makes assumptions about the type of data sent to the server. HTTP_POST() always sets the Content-Type header to application/x-www-form-urlencoded.
Because the Content-type cannot be changed, POSTing any other content type using HTTP_POST() will not work as expected. Instead, HTTP_FETCH() must be used. HTTP_FETCH() allows any header to be set to any value.
Additionally, HTTP_FETCH() supports using the HTTP/1.0 protocol. HTTP_FETCH() will default to HTTP/1.1. HTTP_POST() (and HTTP_GET()) only use HTTP/1.1.
In the example below, a POST request is created and sent using HTTP_FETCH to generate an authentication ticket for accessing the Quickbase API. The Content-type is set to "application/xml" via the settings.header property. The settings dot variable is used to define the protocol, headers, and other instructions for sending the request:
dim settings as p settings.host = "mycompany.quickbase.com" settings.page = "/db/main" settings.protocol = "HTTP/1.0" settings.port = 443 settings.ssl_on = .t. settings.method = "POST" settings.header =<<%txt% Content-Type: application/xml QUICKBASE-ACTION: API_Authenticate %txt% settings.body =<<%body% <qdbapi> <username>[email protected]</username> <password>SomePassword123</password> </qdbapi> %body% dim results as p results = HTTP_FETCH(settings)
Once the response is received, the status code must be checked first to verify that the request was successful (i.e. a status code "200") The status code should always be checked when using any HTTP_* function. The status code can be found in the response.parsed_headers property returned by the HTTP_FETCH() function:
? response.parsed_headers.status_code = 200
If the request succeeds, the response.body will contain the conent from the response. In this example, the content returned is XML:
? results.body = <?xml version="1.0" ?> <qdbapi> <action>API_Authenticate</action> <errcode>0</errcode> <errtext>No error</errtext> <ticket>db4d5y4bd76u86dsd27px44inx72nanzdacmnkwicb3hxxkct7aqr6d</ticket> <userid>123456789</userid> </qdbapi>
See Also