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