Definition
cfhttp is a ColdFusion (CFML) tag that lets your application make HTTP and HTTPS requests to external or internal web resources. In simple terms, it’s the built‑in way for ColdFusion code to call a web page, REST API, or file URL, send data (like form fields or JSON), and read the response that comes back. Think of cfhttp as ColdFusion’s native HTTP client for integrating with other services, performing web requests, and automating fetch or submit tasks.
How CFHTTP Works
The basics: request → response
- You use the
<cfhttp>tag to specify a URL, HTTP method (GET, POST, PUT, DELETE, etc.), and options like timeouts, headers, Authentication, and whether to follow redirects. - Inside
<cfhttp>...</cfhttp>, you may add one or more<cfhttpparam>tags to pass headers, form fields, files (multipart/form-data), or a raw body. - ColdFusion executes the request and returns a structured result (often referenced by the
resultattribute) containing metadata such asstatusCode,mimeType,charset,header, and binary or text content.
This flow lets you connect to REST APIs, Download files, upload documents, and perform web scraping or service‑to‑service communication using standard HTTP.
Syntax and common attributes
Basic GET request:
<cfhttp
url=”https://api.example.com/v1/items”
method=”get”
result=”res”
timeout=”15″>
<cfif res.statusCode EQ “200”>
<cfset bodyAsString = toString(res.fileContent, res.charset ?: "UTF-8")>
POST JSON with headers:
<cfset payload = { name = “Widget”, price = 19.99 }>
<cfhttp
url=”https://api.example.com/v1/items”
method=”post”
result=”res”
timeout=”20″>
Downloading directly to a file (supported in modern ColdFusion versions):
<cfhttp
url=”https://example.com/files/report.csv”
method=”get”
result=”res”
timeout=”30″
path=”C:\data\downloads”
file=”report.csv”>
Useful attributes to know:
url,method,result,timeoutredirect(follow redirects),resolveURLusername,password,authType(HTTP auth)proxyServer,proxyPort,proxyUser,proxyPassworduserAgentmultipart(for file uploads)clientCert,clientCertPassword(mutual TLS)throwOnError(throw exceptions for HTTP errors/connection failures)
Sending parameters with
<cfhttpparam> defines data elements:
type="header": Custom request headers.type="url": Query string parameters (for GET) or form fields (for POST application/x-www-form-urlencoded).type="formField": Form field for multipart/form-data requests.type="file": File attachment in multipart/form-data.type="body": Raw request body (e.g., JSON, XML).
Example multipart upload:
Handling responses
The result struct typically includes:
statusCode(e.g., “200”, “404”)statusText(e.g., “OK”, “Not Found”)responseHeader(struct of headers)mimeType,charsetfileContent(binary of the response body, which you can convert to string viatoString())
Tip: If you expect JSON, detect mimeType and decode with deserializeJson().
<cfif res.statusCode EQ “200” AND findNoCase(“application/json”, res.mimeType)>
<cfset data = deserializeJson(toString(res.fileContent, res.charset ?: “UTF-8”))>
Practical Use Cases
Consuming REST APIs
- Query product catalogs, pricing, shipping rates.
- Retrieve OAuth 2.0 protected resources with Bearer tokens.
- Send webhooks or call third‑party SaaS endpoints.
Web scraping and HTML retrieval
- Fetch HTML to parse with CFML or regex. Use responsibly—respect robots.txt and rate limits.
File uploads and downloads
- Upload images, PDFs, or logs to a cloud endpoint using multipart/form-data.
- Download reports or media and store on disk or in object storage.
Internal service-to-service communication
- Call Microservices behind a firewall with NTLM/Kerberos/Basic auth.
- Use proxies and custom headers to route traffic.
Real-World Example: Poll a Weather API and Cache the Result
Goal: Fetch current conditions for a city, cache for 10 minutes, gracefully handle errors, and avoid hammering the API.
Step 1: Configuration and simple cache key
Step 2: Check cache
<cfif res.statusCode EQ "200">
<cfset body = toString(res.fileContent, res.charset ?: "UTF-8")>
<cfset data = deserializeJson(body)>
<cfset weather = data.current_weather>
<!--- Cache for 10 minutes --->
<cfset cachePut(cacheKey, weather, createTimeSpan(0,0,10,0))>
<cfelse>
<!--- Fallback: log and keep weather as null --->
<cflog text="Weather API error #res.statusCode#: #res.statusText#" file="Integration">
</cfif>
<cfcatch type="any">
<cflog text="Weather API exception: #cfcatch.message#" file="Integration">
</cfcatch>
</cftry>
Step 3: Use it in your view
<cfif NOT isNull(weather)>
What this demonstrates:
- A single CFHTTP GET with a timeout.
- Deserialization from JSON with charset awareness.
- Caching to improve Performance and reduce API calls.
- Error handling with try/catch and logging.
Pros and cons
| Aspect | Pros | Cons |
|---|---|---|
| Integration | Native to CFML; simple, readable Syntax | Less flexible than full-featured Java HTTP libraries for niche cases |
| Productivity | Quick to implement common REST patterns | Large payload processing can be verbose if you need advanced streaming |
| Features | Supports headers, JSON, multipart, auth, proxies, TLS | Advanced auth flows (e.g., OAuth device code) require extra logic |
| Ops | Easy timeouts, redirects, and logging | Needs careful tuning for concurrency and timeouts in high traffic |
Tip: For most applications, CFHTTP is more than sufficient. For exotic needs, you can interop with Java libraries.
Best practices
- Set explicit timeouts
- Use
timeouton every request, e.g., 5–30 seconds, based on the endpoint.
- Use
- Handle errors robustly
- Wrap in
cftry/cfcatch. LogstatusCode,statusText, and response body snippet. ConsiderthrowOnError="true"for strict handling.
- Wrap in
- Validate and sanitize data
- Sanitize dynamic parts of the URL and any headers or form fields to prevent injection issues.
- Use proper headers
- Set
Content-Typecorrectly (application/json, application/xml, multipart/form-data). IncludeAcceptheaders if the API requires them.
- Set
- Manage Authentication
- Store API keys or tokens securely (environment variables, secret vaults). Rotate tokens and handle 401/403 gracefully.
- Respect rate limits
- Cache responses, implement backoff on 429 responses, and add jitter to retries.
- Optimize Performance
- Parallelize independent calls with
cfthreadwhen appropriate. Avoid unnecessary serialization/deserialization. Stream to disk withpath/filefor large downloads.
- Parallelize independent calls with
- Secure transport
- Prefer HTTPS. Validate certificates. For mutual TLS, configure
clientCertandclientCertPassword.
- Prefer HTTPS. Validate certificates. For mutual TLS, configure
- Use consistent user-agent
- Set
userAgentto identify your app; some providers require it.
- Set
- Testing and observability
- Log correlation IDs and request/response times. Mask sensitive data in logs.
- Prefer idempotent methods for retries
- Safe to retry GET/HEAD; be careful with POST/PUT unless the API supports idempotency keys.
Common pitfalls and Troubleshooting
- Wrong content type
- Posting JSON but forgetting
Content-Type: application/jsonleads to 415 Unsupported Media Type.
- Posting JSON but forgetting
- Character encoding issues
- Convert
fileContentusingtoString(res.fileContent, res.charset ?: "UTF-8")to avoid garbled text.
- Convert
- Silent failures due to missing timeouts
- Always set
timeoutto prevent threads hanging.
- Always set
- Misusing multipart
- Use
multipart="yes"andtype="file"for uploads; do not combine rawtype="body"with multipart.
- Use
- Confusing URL vs body params
- For form-encoded POST, use
type="url"for each field; for raw JSON, usetype="body"and set correct header.
- For form-encoded POST, use
- Proxy/auth surprises
- Confirm
proxyServer/proxyPortand auth method (authType) with your infra/Security team.
- Confirm
CFHTTP vs Alternatives
| Option | When to use | Notes |
|---|---|---|
| CFHTTP | Most API calls, web requests, file transfers | Simple and integrated with CFML; supports headers, auth, multipart |
| Java HTTP clients (e.g., Apache HttpClient, Java 11 HttpClient) | Need advanced Features like HTTP/2 push, custom connection pooling | Interop via CFML/Java; more boilerplate |
| cfinvoke / Web services | SOAP/WSDL services | Higher-level SOAP integrations; for REST prefer CFHTTP |
| Database-native connectors | When pulling data directly via JDBC | Not a replacement for HTTP APIs; different integration layer |
Key Points
- CFHTTP is ColdFusion’s built-in HTTP client for making web requests and consuming APIs.
- It supports common HTTP methods, headers, authentication, File upload/download, and SSL/TLS.
- Use
<cfhttpparam>to send headers, form fields, files, or raw bodies like JSON. - Always implement timeouts, Error handling, and caching where appropriate.
- For high-throughput or specialized features, combine CFHTTP with concurrency (
cfthread) and robust logging/monitoring.
FAQ
What HTTP methods does CFHTTP support?
CFHTTP supports standard methods such as GET, POST, PUT, DELETE, HEAD, and OPTIONS. You specify the method with the method attribute.
How do I send JSON in a CFHTTP request?
Set the content type header and pass the serialized body:
<cfhttpparam type="header" name="Content-Type" value="application/json" /><cfhttpparam type="body" value="#serializeJson(data)#" />
How can I handle authentication with CFHTTP?
You can use:
- Basic/Digest/NTLM via
username,password, andauthType. - Token-based auth via headers:
Authorization: Bearer <token>. - Client certificates with
clientCertandclientCertPasswordfor mutual TLS.
How do I avoid timeouts or hung requests?
Always set timeout on <cfhttp>. Implement retry logic where appropriate, back off on 429 or 503, and log slow responses to monitor upstream issues.
Can I upload files with CFHTTP?
Yes. Use multipart="yes" on <cfhttp> and add <cfhttpparam type="file" ...> entries for each file, plus type="formField" for accompanying fields.
