Bug 212858

Summary: Request object methods do not work if Request has a body of FormData
Product: WebKit Reporter: Peter W <peter.b.wu>
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Status: NEW    
Severity: Major CC: ap, cedric, jimmy, mike, motfalcon+wekbitbugs, philip, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari 13   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Result from Safari 13
none
Result from Chrome 83 none

Peter W
Reported 2020-06-05 18:05:13 PDT
When handling POST requests within application Safari, operations such as text, json, arrayBuffer cause a "NotSupportedError: The operation is not supported". When handling POST requests within the developer console in Safari, the same operations do not throw this error.
Attachments
Result from Safari 13 (229.22 KB, image/png)
2020-06-08 15:12 PDT, Peter W
no flags
Result from Chrome 83 (325.34 KB, image/png)
2020-06-08 15:13 PDT, Peter W
no flags
Peter W
Comment 1 2020-06-05 19:06:19 PDT
As an example, using .text() on a GET and a PUT request does not result in any issues.
Peter W
Comment 2 2020-06-05 19:14:20 PDT
When creating a new POST request within the Safari console using the following example, var request = new Request('/', { method: 'POST', body: '{ "foo": "1", "bar": 2 }' }); request.json().then(function(json) { console.log(json.foo); console.log(json.bar); }); However in my application when i try to access the request.text(), theres an error that states "NotSupportedError: The operation is not supported" and I'm not sure whats causing this to occur. function sendRequest(input,requestInit){ // create request object for POST request var request = new Request(input.url, requestInit); // trying to read the clone body will throw the above error Var requestclone = request.clone().text().then(text=>console.log(text)).catch(err=>console.log(err)); fetch(request).then(response=>{ //do stuff here }); When running the same function with a GET or a PUT request, the .text() functions works and I run into no issues. The not supported Error only occurs on a POST request.
Alexey Proskuryakov
Comment 3 2020-06-07 13:21:38 PDT
Please provide a complete test case that reproduces the issue. These properties work in general.
Peter W
Comment 4 2020-06-08 15:12:07 PDT
The following is a test case to reproduce the issue where options such as .text(),.arrayBuffer(), .json(), and .formData() do no work. Note when the body is an instance of FormData, the above methods of inspecting the body element are inaccessible and throw a NotSupportError. When the body is a FormData Object, even the .formData() returns a NotSupportedError. ~~~ var formDataObj = new FormData(); formDataObj.append('key','value') var requestOptions = { cache: "default", credentials: "same-origin", method: "POST", mode: "cors" } var requestOptionsString = { body: "text", cache: "default", credentials: "same-origin", method: "POST", mode: "cors" } var requestOptionsJSON = { body: {"key":"value"}, cache: "default", credentials: "same-origin", method: "POST", mode: "cors" } var requestOptionsFD = { body: formDataObj, cache: "default", credentials: "same-origin", method: "POST", mode: "cors" } function requestTest(input,options){ var request = new Request(input,options) request.clone().formData().then(formData=>console.log("formData",input,formData)).catch(err=>console.log("noFormData",input,err)) request.clone().json().then(json=>console.log("json",input,JSON.stringify(json))).catch(err=>console.log("noJson",input,err)) request.clone().text().then(text=>console.log("text",input,text)).catch(err=>console.log("noText",input,err)) request.clone().arrayBuffer().then(arrayBuffer=>console.log("arrayBuffer",input,arrayBuffer)).catch(err=>console.log("noArrayBuffer",input,err)) request.clone().blob().then(blob=>console.log("blob",input,blob)).catch(err=>console.log("noBlob",input,err)) fetch(request).then(response=>console.log("response",input,response)).catch(error=>console.log("error",input,error)) } requestTest('none',requestOptions) requestTest('string',requestOptionsString) requestTest('json',requestOptionsJSON) requestTest('formData',requestOptionsFD)
Peter W
Comment 5 2020-06-08 15:12:38 PDT
Created attachment 401378 [details] Result from Safari 13
Peter W
Comment 6 2020-06-08 15:13:56 PDT
Created attachment 401379 [details] Result from Chrome 83 Note, that when the body contains a FormData object, the above functions still return a result such as .text() and .formData() when used in chrome.
Alexey Proskuryakov
Comment 7 2020-06-09 16:44:58 PDT
This is not a complete test, as it lacks its server component. Is there any chance you could set up a test server where this reproduces, for end to end debugging?
Peter W
Comment 8 2020-06-09 17:18:11 PDT
I'm confused why you would need to have a server component for this to be a complete test. The fetch at the end of the test function does not need to be there since it doesn't change the fact that the methods do not have access to the body of the request. The issue is that methods request.text(), request.formData() do not work on a body with FormData in safari 13. In fact, it appears none of the methods for accessing the "body" of the request work when the body is of "formData" type. The request exists within the client side. Perhaps a better title for the bug would be "Request object methods do not work if Request has a body of FormData".
Tom
Comment 9 2020-06-09 22:46:21 PDT
Agree with the suggested new title. The problem is not to do with *making* the requests but with preparing them. I think this test captures the issue: new Request('http://localhost', {method: 'POST', body: new FormData()}).arrayBuffer().then(()=>console.log('success')).catch(err=>console.error('Fail: ' + err.message)) In Safari, this will "fail". In Chrome it will succeed. The reason I'm here is that Safari 13.1 introduced FormData support in Service Workers (yay, this is good news). But that meant my polyfill deferred to the new native implementation, but the native implementation cannot handle a Request with FormData as the body. The same behaviour is present in the main/UI thread too, so at least things are consistent I guess. So I'm asking, it would be nice if Request.arrayBuffer() could handle a FormData body :D
Radar WebKit Bug Importer
Comment 10 2020-06-11 18:39:11 PDT
Philip Jägenstedt
Comment 11 2020-08-31 02:28:11 PDT
Was this fixed in bug 215671?
nyro
Comment 12 2021-11-08 07:17:01 PST
Is it related to bug 187461 ?
Note You need to log in before you can comment on or make changes to this bug.