0
# Request Configuration
1
2
Extensions for configuring individual HTTP requests with custom fetch options and JavaScript-specific parameters. This allows per-request customization beyond the engine-level configuration.
3
4
## Capabilities
5
6
### HttpRequestBuilder.fetchOptions Extension
7
8
Extension function that allows configuring individual HTTP requests with custom fetch options.
9
10
```kotlin { .api }
11
/**
12
* Configures HTTP request with custom fetch options.
13
* This allows setting request-specific fetch API options that override engine defaults.
14
*
15
* @param block Configuration block for RequestInit options
16
*/
17
fun HttpRequestBuilder.fetchOptions(block: RequestInit.() -> Unit)
18
```
19
20
**Usage Examples:**
21
22
```kotlin
23
import io.ktor.client.*
24
import io.ktor.client.engine.js.*
25
import io.ktor.client.request.*
26
27
val client = HttpClient(Js)
28
29
// Configure specific request with custom fetch options
30
val response = client.get("https://api.example.com/data") {
31
fetchOptions {
32
credentials = "include"
33
cache = "no-cache"
34
mode = "cors"
35
}
36
}
37
38
// POST request with custom options
39
val postResponse = client.post("https://api.example.com/submit") {
40
fetchOptions {
41
keepalive = true
42
referrer = "no-referrer"
43
}
44
setBody("request data")
45
}
46
```
47
48
### RequestInit Configuration Block
49
50
The configuration block provides access to all standard Fetch API RequestInit options for individual request customization.
51
52
```kotlin { .api }
53
/**
54
* RequestInit interface for configuring fetch options
55
* All properties are optional and override engine-level defaults
56
*/
57
interface RequestInit {
58
/** HTTP method (GET, POST, etc.) - usually set by Ktor automatically */
59
var method: String?
60
61
/** Request headers - can supplement Ktor-managed headers */
62
var headers: dynamic
63
64
/** Request body - usually managed by Ktor */
65
var body: dynamic
66
67
/** Request mode: "cors", "no-cors", "same-origin", "navigate" */
68
var mode: String?
69
70
/** Credentials policy: "omit", "same-origin", "include" */
71
var credentials: String?
72
73
/** Cache control: "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" */
74
var cache: String?
75
76
/** Redirect handling: "follow", "error", "manual" */
77
var redirect: String?
78
79
/** Referrer: URL string, "no-referrer", or "client" */
80
var referrer: String?
81
82
/** Referrer policy for privacy control */
83
var referrerPolicy: String?
84
85
/** Subresource integrity hash */
86
var integrity: String?
87
88
/** Keep connection alive for background requests */
89
var keepalive: Boolean?
90
91
/** AbortController signal for request cancellation */
92
var signal: AbortSignal?
93
94
/** Window object (browser environments only) */
95
var window: dynamic
96
}
97
```
98
99
## Common Request Configuration Patterns
100
101
### Authentication Requests
102
103
```kotlin
104
import io.ktor.client.*
105
import io.ktor.client.engine.js.*
106
import io.ktor.client.request.*
107
108
val client = HttpClient(Js)
109
110
// Request with credentials for authentication
111
val userProfile = client.get("https://api.example.com/profile") {
112
fetchOptions {
113
credentials = "include" // Send cookies and auth headers
114
}
115
}
116
117
// API request with no credentials
118
val publicData = client.get("https://api.example.com/public") {
119
fetchOptions {
120
credentials = "omit" // Don't send any credentials
121
}
122
}
123
```
124
125
### Cache Control Per Request
126
127
```kotlin
128
// Force fresh data from server
129
val freshData = client.get("https://api.example.com/live-data") {
130
fetchOptions {
131
cache = "no-cache" // Validate with server
132
}
133
}
134
135
// Use cached data if available
136
val cachedData = client.get("https://api.example.com/static-data") {
137
fetchOptions {
138
cache = "force-cache" // Use cache if available
139
}
140
}
141
142
// Never cache sensitive data
143
val sensitiveData = client.get("https://api.example.com/sensitive") {
144
fetchOptions {
145
cache = "no-store" // Never cache this response
146
}
147
}
148
```
149
150
### CORS Requests
151
152
```kotlin
153
// Cross-origin request with specific CORS settings
154
val corsResponse = client.post("https://external-api.com/endpoint") {
155
fetchOptions {
156
mode = "cors"
157
credentials = "same-origin"
158
referrerPolicy = "strict-origin-when-cross-origin"
159
}
160
setBody(jsonData)
161
}
162
163
// Same-origin only request
164
val sameOriginResponse = client.get("https://same-domain.com/api") {
165
fetchOptions {
166
mode = "same-origin" // Fail if cross-origin
167
}
168
}
169
```
170
171
### Background Requests
172
173
```kotlin
174
// Fire-and-forget background request
175
val analyticsResult = client.post("https://analytics.example.com/event") {
176
fetchOptions {
177
keepalive = true // Keep connection alive even if page unloads
178
}
179
setBody(analyticsData)
180
}
181
182
// Background sync with custom referrer
183
val syncResult = client.put("https://sync.example.com/data") {
184
fetchOptions {
185
keepalive = true
186
referrer = "no-referrer" // Privacy protection
187
}
188
setBody(syncData)
189
}
190
```
191
192
### Request Cancellation
193
194
```kotlin
195
import org.w3c.dom.AbortController
196
197
// Create abort controller for cancellation
198
val controller = AbortController()
199
200
// Request with cancellation support
201
val cancelableRequest = async {
202
client.get("https://api.example.com/slow-endpoint") {
203
fetchOptions {
204
signal = controller.signal
205
}
206
}
207
}
208
209
// Cancel the request after 5 seconds
210
delay(5000)
211
controller.abort()
212
```
213
214
### Security Headers
215
216
```kotlin
217
// Request with integrity checking
218
val secureResponse = client.get("https://cdn.example.com/library.js") {
219
fetchOptions {
220
integrity = "sha384-abc123def456..." // Expected hash
221
referrer = "no-referrer" // Don't leak referrer
222
cache = "default" // Allow caching of verified content
223
}
224
}
225
226
// Privacy-focused request
227
val privateResponse = client.get("https://api.example.com/data") {
228
fetchOptions {
229
referrerPolicy = "no-referrer"
230
mode = "cors"
231
credentials = "omit" // No credentials for privacy
232
}
233
}
234
```
235
236
## Integration with Ktor Features
237
238
### Combining with Request Builders
239
240
```kotlin
241
import io.ktor.client.request.*
242
import io.ktor.http.*
243
244
val response = client.post("https://api.example.com/upload") {
245
// Standard Ktor configuration
246
contentType(ContentType.Application.Json)
247
setBody(requestData)
248
timeout {
249
requestTimeoutMillis = 30000
250
}
251
252
// JavaScript-specific fetch options
253
fetchOptions {
254
keepalive = true
255
cache = "no-store"
256
credentials = "include"
257
}
258
}
259
```
260
261
### With Custom Headers
262
263
```kotlin
264
val response = client.get("https://api.example.com/data") {
265
// Ktor header management
266
header("Authorization", "Bearer $token")
267
header("Accept", "application/json")
268
269
// Fetch-specific options
270
fetchOptions {
271
mode = "cors"
272
credentials = "omit" // Don't send cookies despite Authorization header
273
referrerPolicy = "strict-origin"
274
}
275
}
276
```
277
278
## Platform Considerations
279
280
- **Browser**: All RequestInit options work as per Fetch API specification
281
- **Node.js**: Some browser-specific options like `window` are ignored
282
- **WASM-JS**: Limited support for advanced options depending on runtime capabilities
283
284
## Error Handling
285
286
Configuration errors in `fetchOptions` are handled by the underlying Fetch API:
287
288
```kotlin
289
try {
290
val response = client.get("https://api.example.com") {
291
fetchOptions {
292
mode = "same-origin" // Will fail for cross-origin requests
293
}
294
}
295
} catch (error: JsError) {
296
// Handle fetch configuration errors
297
println("Fetch error: ${error.origin}")
298
}
299
```