@@ -15,13 +15,15 @@ export interface HttpOptions {
1515 xsrfUrl ?: string | false
1616 client ?: HttpClient
1717 lang ?: Lang
18+ payloadKey ?: string
1819}
1920
2021export class Http {
2122 private static baseUrl : string | undefined = undefined
2223 private static xsrfUrl : string | false = '/api/csrf-cookie'
2324 private static client : HttpClient = ofetch
2425 private static lang : Lang | undefined = undefined
26+ private static payloadKey = '__payload__'
2527
2628 static config ( options : HttpOptions ) {
2729 if ( options . baseUrl ) {
@@ -36,6 +38,9 @@ export class Http {
3638 if ( options . lang ) {
3739 Http . lang = options . lang
3840 }
41+ if ( options . payloadKey ) {
42+ Http . payloadKey = options . payloadKey
43+ }
3944 }
4045
4146 private async ensureXsrfToken ( ) : Promise < string | undefined > {
@@ -101,6 +106,26 @@ export class Http {
101106 }
102107
103108 async post < T = any > ( url : string , body ?: any , options ?: FetchOptions ) : Promise < T > {
109+ if ( body && ! ( body instanceof FormData ) ) {
110+ let hasFile = false
111+
112+ const payload = JSON . stringify ( body , ( _ , value ) => {
113+ if ( value instanceof Blob ) {
114+ hasFile = true
115+ return undefined
116+ }
117+ return value
118+ } )
119+
120+ if ( hasFile ) {
121+ const formData = this . objectToFormData ( body , undefined , undefined , true )
122+ formData . append ( Http . payloadKey , payload )
123+ body = formData
124+ } else {
125+ body = payload
126+ }
127+ }
128+
104129 return this . performRequest < T > ( url , { method : 'POST' , body, ...options } )
105130 }
106131
@@ -117,13 +142,7 @@ export class Http {
117142 }
118143
119144 async upload < T = any > ( url : string , body ?: any , options ?: FetchOptions ) : Promise < T > {
120- const formData = this . objectToFormData ( body )
121-
122- return this . performRequest < T > ( url , {
123- method : 'POST' ,
124- body : formData ,
125- ...options
126- } )
145+ return this . post < T > ( url , this . objectToFormData ( body ) , options )
127146 }
128147
129148 async download ( url : string , options ?: FetchOptions ) : Promise < void > {
@@ -143,7 +162,7 @@ export class Http {
143162 FileSaver . saveAs ( blob , filename as string )
144163 }
145164
146- private objectToFormData ( obj : any , form ?: FormData , namespace ?: string ) {
165+ private objectToFormData ( obj : any , form ?: FormData , namespace ?: string , onlyFiles = false ) {
147166 const fd = form || new FormData ( )
148167 let formKey : string
149168
@@ -163,9 +182,12 @@ export class Http {
163182 && ! ( obj [ property ] instanceof Blob )
164183 && obj [ property ] !== null
165184 ) {
166- this . objectToFormData ( obj [ property ] , fd , property )
185+ this . objectToFormData ( obj [ property ] , fd , property , onlyFiles )
167186 } else {
168187 const value = obj [ property ] === null ? '' : obj [ property ]
188+ if ( onlyFiles && ! ( value instanceof Blob ) ) {
189+ return
190+ }
169191 fd . append ( formKey , value )
170192 }
171193 } )
0 commit comments