Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using FormRequest with 'file' validation, request data is empty even data is provided in docs example body #764

Closed
1 task done
lHondol opened this issue Dec 1, 2023 · 4 comments · Fixed by #864
Labels
bug Something isn't working triage

Comments

@lHondol
Copy link

lHondol commented Dec 1, 2023

Scribe version

4.23

PHP version

8.2.4

Framework

Laravel

Framework version

10

Scribe config

theme => "elements"
title => "Notex"                  
base_url => "http://localhost:8000"           
try_it_out.base_url => "http://localhost:8000"
auth.enabled => true
auth.default => true
auth.name => "Authorization"

What happened?

In my FormRequest, i have these rules:

public function rules(): array
{
    return [
        'information' => ['required'],
        'file' => ['required', 'file'],
    ];
}

In the generated documentation, within the "try_out" body, I can now choose the file I need to upload. However, when I hit submit, the response states, 'The information field is required,' even though I have already provided the value.

also the request payload:

------WebKitFormBoundaryPuRQG2gkhYZdgo8K
Content-Disposition: form-data; name="information"


tempore

------WebKitFormBoundaryPuRQG2gkhYZdgo8K
Content-Disposition: form-data; name="file"; filename="myfile.pdf"
Content-Type: application/pdf


------WebKitFormBoundaryPuRQG2gkhYZdgo8K--

request headers :
Content-Type: 'multipart/form-data'
Accept: 'application/json'

Docs

@lHondol lHondol added bug Something isn't working triage labels Dec 1, 2023
@mcpicoli
Copy link

mcpicoli commented Dec 15, 2023

Having similar trouble here using try-it-out. Route uses HTTP PUT method and has a "file" parameter named "photo". php artisan scribe:generate generates "correct" documentation, I can pick a file and fill other parameters. If no file is selected, everything works fine, only when providing it, it is missing as described by the OP.

#257 should have fixed this problem, but the HTTP method is never changed to POST, the hidden parameter "_method" is never added and the Content-Type header is never changed to multipart/form-data. The file is never seen by the server (as expected since PUT does not support multipart/form-data in PHP) and because of that the validation logic fails, stating the file is invalid since it is encoded as an empty JSON body.

{"photo":{}}

The request header, as per the browser developer tools is not changed from "Content-Type: application/json"

If I change the header manually to "multipart/form-data", the validation logic passes (the file is not mandatory), but the try-it-out does not send anything multipart encoded (file is missing), nothing is done at all regarding the file. The correct (manually changed) Content-Type is sent, but (if I am not understanding something wrong), it should be deleted (line 192)

Edit: version here is 4.25.0

@shalvah
Copy link
Contributor

shalvah commented Dec 21, 2023

Thanks for your preliminary investigation. I'll look at this some more when I have the time, but in the meantime, feel free to submit a PR if you have an idea what needs to be fixed.

@wlhrtr
Copy link
Contributor

wlhrtr commented Jun 6, 2024

When uploading a file the Content-Type header must not be set otherwise the browser cannot set the right boundaries for the multipart formdata payload.

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest_API/Using_FormData_Objects
Bildschirmfoto 2024-06-06 um 12 07 56

You can add following code to index.blade.php of vendor published elements template in line :126 to get it to work

// ...
let preflightPromise = Promise.resolve();
if (window.useCsrf && window.csrfUrl) {
    preflightPromise = makeAPICall('GET', window.csrfUrl).then(() => {
        headers['X-XSRF-TOKEN'] = getCookie('XSRF-TOKEN');
    });
}

// START this needs to be added
if (form.dataset.hasfiles === "1") {
    delete headers['Content-Type'];
}
// END this needs to be added

return preflightPromise.then(() => makeAPICall(method, path, body, query, headers, endpointId))
// ...

@shalvah
Copy link
Contributor

shalvah commented Jun 10, 2024

Can you make a PR with that fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants