Explore all File Upload open source software, libraries, packages, source code, cloud functions and APIs.

Popular New Releases in File Upload

uppy

Uppy 2.9.3

dropzone

Release v5.9.2

filepond

4.28.2

bootstrap-fileinput

Version 5.2.3

angular-file-upload

2.6.1

Popular Libraries in File Upload

jQuery-File-Upload

by blueimp doticonphpdoticon

star image 31080 doticonMIT

File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.

uppy

by transloadit doticonjavascriptdoticon

star image 25143 doticonMIT

The next open source file uploader for web browsers :dog:

dropzone

by dropzone doticonjavascriptdoticon

star image 15704 doticonNOASSERTION

Dropzone is an easy to use drag'n'drop library. It supports image previews and shows nice progress bars.

filepond

by pqina doticonjavascriptdoticon

star image 12102 doticonMIT

🌊 A flexible and fun JavaScript file upload library

ng-file-upload

by danialfarid doticonjavascriptdoticon

star image 7979 doticonMIT

Lightweight Angular directive to upload files with optional FileAPI shim for cross browser support

bootstrap-fileinput

by kartik-v doticonjavascriptdoticon

star image 5024 doticonNOASSERTION

An enhanced HTML 5 file input for Bootstrap 5.x/4.x./3.x with file preview, multiple selection, and more features.

resumable.js

by 23 doticonjavascriptdoticon

star image 4318 doticonMIT

A JavaScript library for providing multiple simultaneous, stable, fault-tolerant and resumable/restartable uploads via the HTML5 File API.

angular-file-upload

by nervgh doticonjavascriptdoticon

star image 3487 doticonMIT

[ALMOST NOT MAINTAINED] Angular File Upload is a module for the AngularJS framework

flow.js

by flowjs doticonjavascriptdoticon

star image 2834 doticonMIT

A JavaScript library providing multiple simultaneous, stable, fault-tolerant and resumable/restartable file uploads via the HTML5 File API.

Trending New libraries in File Upload

BaiduPCS-Go

by felixonmars doticongodoticon

star image 772 doticonApache-2.0

Re-upload of iikira/BaiduPCS-Go

laravel-media-uploader

by ahmed-aliraqi doticonphpdoticon

star image 283 doticon

This package used to upload files using laravel-media-library before saving model.

react-upload-box

by cheersmas doticontypescriptdoticon

star image 186 doticonMIT

A minimal Upload component for React.

next-s3-upload

by ryanto doticonjavascriptdoticon

star image 170 doticonMIT

Upload files from your Next.js app to S3

cloudinary-laravel

by cloudinary-labs doticonphpdoticon

star image 162 doticonMIT

Laravel SDK for Cloudinary

ipfs-action

by aquiladev doticonjavascriptdoticon

star image 110 doticonMIT

GitHub Action for upload to IPFS. Supports Pinata, Infura pinning service as well as direct upload.

svelte-filepond

by pqina doticonjavascriptdoticon

star image 98 doticonMIT

🔌 A handy FilePond adapter component for Svelte

react-native-blob-courier

by edeckers doticonkotlindoticon

star image 92 doticonMPL-2.0

Use this library to efficiently download and upload blobs in React Native.

super-tinypng

by zhanyuzhang doticonjavascriptdoticon

star image 76 doticon

Tinypng without "Too many files uploaded at once" limit

Top Authors in File Upload

1

pqina

12 Libraries

star icon15469

2

filestack

9 Libraries

star icon670

3

bezkoder

8 Libraries

star icon59

4

uploadcare

7 Libraries

star icon343

5

tus

6 Libraries

star icon2433

6

FineUploader

6 Libraries

star icon442

7

SinghDigamber

5 Libraries

star icon21

8

bennadel

4 Libraries

star icon27

9

gorails-screencasts

4 Libraries

star icon27

10

UniSharp

4 Libraries

star icon1859

1

12 Libraries

star icon15469

2

9 Libraries

star icon670

3

8 Libraries

star icon59

4

7 Libraries

star icon343

5

6 Libraries

star icon2433

6

6 Libraries

star icon442

7

5 Libraries

star icon21

8

4 Libraries

star icon27

9

4 Libraries

star icon27

10

4 Libraries

star icon1859

Trending Kits in File Upload

Here are some best React File Uploader Libraries. React File Uploader Libraries' use cases include Image Uploads, File Storage, Data Visualization, and Third-Party Services.  


React file uploader libraries are libraries of code that enable developers to create and implement file-uploading functionality in React applications. These libraries typically handle the loading, displaying, and manipulation of files and provide features such as validation, progress tracking, and security.  


Let us look at these libraries in detail below. 

react-dropzone

  • Allows users to drag and drop files directly into the browser window for uploading.
  • Built-in support for previewing images and other file types before uploading.
  • Multiple file uploads can be configured to accept multiple file types.

uppload

  • Supports powerful image editing capabilities.
  • Supports direct uploads to Amazon S3.
  • Can be integrated with Cloudinary, allowing for fast, secure, and easy image and video processing. 

react-filepond

  • Supports serverless uploads.
  • Supports basic image editing capabilities.
  • Supports file type validation.

React-Dropzone-Component

  • Offers an intuitive, declarative API.
  • Provides an optional image preview feature.
  • Offers a wide range of customization options.

react-uploady

  • Multiple authentication methods.
  • Built-in security features.
  • Support for multiple languages.

react-dropzone-uploader

  • Supports both single and multiple file uploads.
  • Allows for automatic resizing of images as they're uploaded.
  • Supports server-side file validation.

react-firebase-file-uploader

  • Upload files directly to Firebase Storage, not just the web server. 
  • Easy way to track and visualize the progress of file uploads in real time. 
  • Lets you customize the look and feel of your uploader. 

react_file_uploader

  • Provides a robust, highly configurable uploader.
  • Supports chunked file uploads.
  • Can select multiple files to upload at once.

Trending Discussions on File Upload

Azure ASP.NET Core web api returns 404 for proxied multipart/form-data request

php ajax file upload not working - partial file upload error

How to get data point label using click in plotly

How to upload a stream to S3 with AWS SDK v3

Spring Boot 2.5.x: Required request part 'file' is not present

How to get a upload button in swagger for IFormFile combined with other properties?

Problem dealing with a space when moving JSON to Python

Java can't upload file with @Pathvariable optional

Antd File upload not getting reset

Load byte[] Property of Class Only When Needed

QUESTION

Azure ASP.NET Core web api returns 404 for proxied multipart/form-data request

Asked 2022-Mar-11 at 08:40

I'm new to Azure and trying to set up my nextjs client app and my ASP.NET Core backend app. Everything seems to play well now, except for file uploads. It's working on localhost, but in production the backend returns a 404 web page (attached image) before reaching the actual API endpoint. I've also successfully tested to make a multipart/form-data POST request in Postman from my computer.

404 Response

The way I implemented this is that I'm proxying the upload from the browser through an api route (client's server side) to the backend. I have to go via the client server side to append a Bearer token from a httpOnly cookie.

I've enabled CORS in Startup.cs:

1app.UseCors(builder => { builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); });
2

The frontend and backend apps are running in individual services and I've tried to enable CORS in the Azure portal as well, but there I could only allow origins, not headers and methods? The error message doesn't indicate CORS problems, but I just wanted make sure..

As far as I can see the requests look good, with correct URLs and origins. I suspect I'm missing some config in azure, but I didn't get any further by following the hints in the error message.

Any suggestions to what may cause this? Or where I can start looking. I'm not quite sure where to look for log output for this issue.

ANSWER

Answered 2022-Mar-10 at 06:35
  • Cross-Origin Resource Sharing (CORS) allows JavaScript code running in a browser on an external host to interact with your backend.

  • To allow all, use "*" and remove all other origins from the list.

I could only allow origins, not headers and methods?

Add the below configuration in your web.config file to allow headers and methods.

1app.UseCors(builder => { builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); });
2<system.webServer>
3  <httpProtocol>
4    <customHeaders>
5      <add  name="Access-Control-Allow-Origin"  value="*"  />
6      <add  name="Access-Control-Allow-Headers"  value="Content-Type"  />
7      <add  name="Access-Control-Allow-Methods"  value="GET, POST, PUT, DELETE, OPTIONS"  />
8    </customHeaders>
9  </httpProtocol>
10</system.webServer>
11

Add the below snippet in web.config=><system.webServer> =>handlers tag

1app.UseCors(builder =&gt; { builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); });
2&lt;system.webServer&gt;
3  &lt;httpProtocol&gt;
4    &lt;customHeaders&gt;
5      &lt;add  name=&quot;Access-Control-Allow-Origin&quot;  value=&quot;*&quot;  /&gt;
6      &lt;add  name=&quot;Access-Control-Allow-Headers&quot;  value=&quot;Content-Type&quot;  /&gt;
7      &lt;add  name=&quot;Access-Control-Allow-Methods&quot;  value=&quot;GET, POST, PUT, DELETE, OPTIONS&quot;  /&gt;
8    &lt;/customHeaders&gt;
9  &lt;/httpProtocol&gt;
10&lt;/system.webServer&gt;
11&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
12&lt;configuration&gt;
13    &lt;location path=&quot;.&quot; inheritInChildApplications=&quot;false&quot;&gt;
14        &lt;system.webServer&gt;
15            &lt;handlers&gt;
16                &lt;add name=&quot;aspNetCore&quot; path=&quot;*&quot; verb=&quot;*&quot; modules=&quot;AspNetCoreModuleV2&quot; resourceType=&quot;Unspecified&quot; /&gt;
17            &lt;/handlers&gt;
18            &lt;aspNetCore processPath=&quot;dotnet&quot; arguments=&quot;.\yourURI.dll&quot; stdoutLogEnabled=&quot;false&quot; stdoutLogFile=&quot;\\?\%home%\LogFiles\stdout&quot; hostingModel=&quot;InProcess&quot; /&gt;
19        &lt;/system.webServer&gt;
20    &lt;/location&gt;
21&lt;/configuration&gt;
22
  • Make sure the routing is done properly

[Route("api/[controller]")] should be in your controller class.

client cache is still pointing to the domain to ols ip address. clear the cache by running the command ipconfig/flushdns

Please refer Custom domain has not been configured inside Azure ,Azure WebApps Custom Domain 404 error - Flush DNS and SO Thread for more information

Source https://stackoverflow.com/questions/71335834

QUESTION

php ajax file upload not working - partial file upload error

Asked 2022-Mar-02 at 11:40

I've written code for uploading a file along with other form inputs using html, ajax and php. I'm submitting the form using ajax. Everything is working in one server, but when I moved the code to a new server, I keep getting PARTIAL FILE UPLOAD ERROR.

Sample code is given below

HTML:

1&lt;form id=&quot;gal-form&quot; class=&quot;form-gallery&quot; enctype=&quot;multipart/form-data&quot;&gt;
2    &lt;input type=&quot;hidden&quot; id=&quot;gal_id&quot; name=&quot;id&quot; value=&quot;&quot;&gt;
3    &lt;div class=&quot;up-types&quot;&gt;
4        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
5            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
6            &lt;input type=&quot;text&quot; value=&quot;ebooks&quot; disabled=&quot;&quot;&gt;
7            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;ebooks&quot; id=&quot;links_to_3&quot; value=&quot;&quot;&gt;
8        &lt;/div&gt;
9        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
10            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
11            &lt;input type=&quot;text&quot; value=&quot;handbooks&quot; disabled=&quot;&quot;&gt;
12            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;handbooks&quot; id=&quot;links_to_4&quot; value=&quot;&quot;&gt;
13        &lt;/div&gt;
14        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
15            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
16            &lt;input type=&quot;text&quot; value=&quot;manuals&quot; disabled=&quot;&quot;&gt;
17            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;manuals&quot; id=&quot;links_to_5&quot; value=&quot;&quot;&gt;
18        &lt;/div&gt;
19    &lt;/div&gt;
20    &lt;div class=&quot;form-group&quot;&gt;
21        &lt;label for=&quot;gal_title&quot;&gt;Title&lt;/label&gt;
22        &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;gal_title&quot; name=&quot;title&quot; placeholder=&quot;Add a title here..&quot;&gt;
23    &lt;/div&gt;
24    &lt;div class=&quot;form-group&quot;&gt;
25        &lt;label for=&quot;gal_title&quot;&gt;Category&lt;/label&gt;
26        &lt;input id=&quot;gallery_tags&quot; class=&quot;form-control&quot; name=&quot;tags[]&quot; type=&quot;text&quot; value=&quot;&quot; placeholder=&quot;Add a category here..&quot;&gt;
27    &lt;/div&gt;
28    &lt;div class=&quot;form-group&quot;&gt;
29        &lt;label&gt;File upload &lt;span class=&quot;text-danger&quot;&gt;*Only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp;amp; PNG files are allowed. Please try to upload images/videos of a specific aspect ratio&lt;/span&gt;&lt;/label&gt;
30        &lt;input type=&quot;file&quot; name=&quot;gal&quot; id=&quot;gal-file&quot; class=&quot;file-upload-default&quot;&gt;
31        &lt;div class=&quot;input-group col-xs-12&quot;&gt;
32            &lt;input type=&quot;text&quot; class=&quot;form-control file-upload-info&quot; disabled=&quot;&quot; placeholder=&quot;Upload File&quot;&gt;
33            &lt;span class=&quot;input-group-append&quot;&gt;
34                &lt;button class=&quot;file-upload-browse btn btn-primary&quot; type=&quot;button&quot;&gt;Browse&lt;/button&gt;
35            &lt;/span&gt;
36        &lt;/div&gt;
37    &lt;/div&gt;
38    &lt;div class=&quot;form-group&quot;&gt;
39        &lt;label for=&quot;event_text&quot;&gt;Description&lt;/label&gt;
40        &lt;textarea class=&quot;form-control&quot; id=&quot;media_desc&quot; name=&quot;desc&quot; rows=&quot;4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/textarea&gt;
41    &lt;/div&gt;
42    &lt;button type=&quot;submit&quot; id=&quot;gal-button&quot; class=&quot;btn btn-primary mr-2&quot;&gt;Submit&lt;/button&gt;
43&lt;/form&gt;
44

I've to set some parameters from javascript, so,

1&lt;form id=&quot;gal-form&quot; class=&quot;form-gallery&quot; enctype=&quot;multipart/form-data&quot;&gt;
2    &lt;input type=&quot;hidden&quot; id=&quot;gal_id&quot; name=&quot;id&quot; value=&quot;&quot;&gt;
3    &lt;div class=&quot;up-types&quot;&gt;
4        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
5            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
6            &lt;input type=&quot;text&quot; value=&quot;ebooks&quot; disabled=&quot;&quot;&gt;
7            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;ebooks&quot; id=&quot;links_to_3&quot; value=&quot;&quot;&gt;
8        &lt;/div&gt;
9        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
10            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
11            &lt;input type=&quot;text&quot; value=&quot;handbooks&quot; disabled=&quot;&quot;&gt;
12            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;handbooks&quot; id=&quot;links_to_4&quot; value=&quot;&quot;&gt;
13        &lt;/div&gt;
14        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
15            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
16            &lt;input type=&quot;text&quot; value=&quot;manuals&quot; disabled=&quot;&quot;&gt;
17            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;manuals&quot; id=&quot;links_to_5&quot; value=&quot;&quot;&gt;
18        &lt;/div&gt;
19    &lt;/div&gt;
20    &lt;div class=&quot;form-group&quot;&gt;
21        &lt;label for=&quot;gal_title&quot;&gt;Title&lt;/label&gt;
22        &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;gal_title&quot; name=&quot;title&quot; placeholder=&quot;Add a title here..&quot;&gt;
23    &lt;/div&gt;
24    &lt;div class=&quot;form-group&quot;&gt;
25        &lt;label for=&quot;gal_title&quot;&gt;Category&lt;/label&gt;
26        &lt;input id=&quot;gallery_tags&quot; class=&quot;form-control&quot; name=&quot;tags[]&quot; type=&quot;text&quot; value=&quot;&quot; placeholder=&quot;Add a category here..&quot;&gt;
27    &lt;/div&gt;
28    &lt;div class=&quot;form-group&quot;&gt;
29        &lt;label&gt;File upload &lt;span class=&quot;text-danger&quot;&gt;*Only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp;amp; PNG files are allowed. Please try to upload images/videos of a specific aspect ratio&lt;/span&gt;&lt;/label&gt;
30        &lt;input type=&quot;file&quot; name=&quot;gal&quot; id=&quot;gal-file&quot; class=&quot;file-upload-default&quot;&gt;
31        &lt;div class=&quot;input-group col-xs-12&quot;&gt;
32            &lt;input type=&quot;text&quot; class=&quot;form-control file-upload-info&quot; disabled=&quot;&quot; placeholder=&quot;Upload File&quot;&gt;
33            &lt;span class=&quot;input-group-append&quot;&gt;
34                &lt;button class=&quot;file-upload-browse btn btn-primary&quot; type=&quot;button&quot;&gt;Browse&lt;/button&gt;
35            &lt;/span&gt;
36        &lt;/div&gt;
37    &lt;/div&gt;
38    &lt;div class=&quot;form-group&quot;&gt;
39        &lt;label for=&quot;event_text&quot;&gt;Description&lt;/label&gt;
40        &lt;textarea class=&quot;form-control&quot; id=&quot;media_desc&quot; name=&quot;desc&quot; rows=&quot;4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/textarea&gt;
41    &lt;/div&gt;
42    &lt;button type=&quot;submit&quot; id=&quot;gal-button&quot; class=&quot;btn btn-primary mr-2&quot;&gt;Submit&lt;/button&gt;
43&lt;/form&gt;
44$(&quot;#gal-form&quot;).on('submit', function(e) {
45    e.preventDefault();
46    var desc = &quot;Some description here&quot;;
47
48    if ($('#gal_title').val() == '') {
49        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter title name...&lt;/span&gt;');
50        return false;
51    } else if ($('#gal-file').get(0).files.length === 0 &amp;&amp; !desc) {
52        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter a description or choose a file to upload...&lt;/span&gt;');
53        return false;
54    } 
55
56    var formData = new FormData(this);
57    var values = $(&quot;input[name='links[]']:enabled&quot;).map(function() {
58        let id = this.id.split(&quot;_&quot;).pop();
59        let link = $(this).data(&quot;type&quot;);
60        if (this.value) {
61            link += &quot;/&quot; + this.value;
62        }
63        return {
64            id: id,
65            link: link
66        };
67    }).get();
68    formData.append('links_to', JSON.stringify(values));
69    formData.set('desc',desc);
70
71    $.ajax({
72        type: 'POST',
73        url: 'url',
74        data: formData,
75        dataType: 'json',
76        contentType: false,
77        cache: false,
78        processData: false,
79        success: function(obj) {
80            if (obj.success) {
81                window.location.reload();
82            } else {
83                alertItem(obj.error);
84            }
85        },
86        error: function(request, status, error) {
87            alertItem(request.responseText);
88        }
89    });
90});
91

And in PHP,

1&lt;form id=&quot;gal-form&quot; class=&quot;form-gallery&quot; enctype=&quot;multipart/form-data&quot;&gt;
2    &lt;input type=&quot;hidden&quot; id=&quot;gal_id&quot; name=&quot;id&quot; value=&quot;&quot;&gt;
3    &lt;div class=&quot;up-types&quot;&gt;
4        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
5            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
6            &lt;input type=&quot;text&quot; value=&quot;ebooks&quot; disabled=&quot;&quot;&gt;
7            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;ebooks&quot; id=&quot;links_to_3&quot; value=&quot;&quot;&gt;
8        &lt;/div&gt;
9        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
10            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
11            &lt;input type=&quot;text&quot; value=&quot;handbooks&quot; disabled=&quot;&quot;&gt;
12            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;handbooks&quot; id=&quot;links_to_4&quot; value=&quot;&quot;&gt;
13        &lt;/div&gt;
14        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
15            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
16            &lt;input type=&quot;text&quot; value=&quot;manuals&quot; disabled=&quot;&quot;&gt;
17            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;manuals&quot; id=&quot;links_to_5&quot; value=&quot;&quot;&gt;
18        &lt;/div&gt;
19    &lt;/div&gt;
20    &lt;div class=&quot;form-group&quot;&gt;
21        &lt;label for=&quot;gal_title&quot;&gt;Title&lt;/label&gt;
22        &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;gal_title&quot; name=&quot;title&quot; placeholder=&quot;Add a title here..&quot;&gt;
23    &lt;/div&gt;
24    &lt;div class=&quot;form-group&quot;&gt;
25        &lt;label for=&quot;gal_title&quot;&gt;Category&lt;/label&gt;
26        &lt;input id=&quot;gallery_tags&quot; class=&quot;form-control&quot; name=&quot;tags[]&quot; type=&quot;text&quot; value=&quot;&quot; placeholder=&quot;Add a category here..&quot;&gt;
27    &lt;/div&gt;
28    &lt;div class=&quot;form-group&quot;&gt;
29        &lt;label&gt;File upload &lt;span class=&quot;text-danger&quot;&gt;*Only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp;amp; PNG files are allowed. Please try to upload images/videos of a specific aspect ratio&lt;/span&gt;&lt;/label&gt;
30        &lt;input type=&quot;file&quot; name=&quot;gal&quot; id=&quot;gal-file&quot; class=&quot;file-upload-default&quot;&gt;
31        &lt;div class=&quot;input-group col-xs-12&quot;&gt;
32            &lt;input type=&quot;text&quot; class=&quot;form-control file-upload-info&quot; disabled=&quot;&quot; placeholder=&quot;Upload File&quot;&gt;
33            &lt;span class=&quot;input-group-append&quot;&gt;
34                &lt;button class=&quot;file-upload-browse btn btn-primary&quot; type=&quot;button&quot;&gt;Browse&lt;/button&gt;
35            &lt;/span&gt;
36        &lt;/div&gt;
37    &lt;/div&gt;
38    &lt;div class=&quot;form-group&quot;&gt;
39        &lt;label for=&quot;event_text&quot;&gt;Description&lt;/label&gt;
40        &lt;textarea class=&quot;form-control&quot; id=&quot;media_desc&quot; name=&quot;desc&quot; rows=&quot;4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/textarea&gt;
41    &lt;/div&gt;
42    &lt;button type=&quot;submit&quot; id=&quot;gal-button&quot; class=&quot;btn btn-primary mr-2&quot;&gt;Submit&lt;/button&gt;
43&lt;/form&gt;
44$(&quot;#gal-form&quot;).on('submit', function(e) {
45    e.preventDefault();
46    var desc = &quot;Some description here&quot;;
47
48    if ($('#gal_title').val() == '') {
49        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter title name...&lt;/span&gt;');
50        return false;
51    } else if ($('#gal-file').get(0).files.length === 0 &amp;&amp; !desc) {
52        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter a description or choose a file to upload...&lt;/span&gt;');
53        return false;
54    } 
55
56    var formData = new FormData(this);
57    var values = $(&quot;input[name='links[]']:enabled&quot;).map(function() {
58        let id = this.id.split(&quot;_&quot;).pop();
59        let link = $(this).data(&quot;type&quot;);
60        if (this.value) {
61            link += &quot;/&quot; + this.value;
62        }
63        return {
64            id: id,
65            link: link
66        };
67    }).get();
68    formData.append('links_to', JSON.stringify(values));
69    formData.set('desc',desc);
70
71    $.ajax({
72        type: 'POST',
73        url: 'url',
74        data: formData,
75        dataType: 'json',
76        contentType: false,
77        cache: false,
78        processData: false,
79        success: function(obj) {
80            if (obj.success) {
81                window.location.reload();
82            } else {
83                alertItem(obj.error);
84            }
85        },
86        error: function(request, status, error) {
87            alertItem(request.responseText);
88        }
89    });
90});
91$uploadStatus = 1; 
92$data = array();
93if(!empty($_FILES[&quot;gal&quot;][&quot;name&quot;])){ 
94    $file_name = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]),PATHINFO_FILENAME);
95    $fileType = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]), PATHINFO_EXTENSION);
96
97    $fileName = $this-&gt;generateSlug($file_name).'_'.time().'.'.$fileType; 
98    $targetFilePath = $fileName; 
99        
100    $allowTypes = array('pdf', 'mp4', 'webm', 'ogg', 'jpg', 'png', 'jpeg'); 
101    if(in_array(strtolower($fileType), $allowTypes)){ 
102        if(move_uploaded_file($_FILES[&quot;gal&quot;][&quot;tmp_name&quot;], $targetFilePath)){ 
103            $data['file'] = $fileName;
104        }else{ 
105            $uploadStatus = 0; 
106            return  array('error'=&gt;$_FILES[&quot;error&quot;])); 
107        } 
108    }else{ 
109        $uploadStatus = 0; 
110        return  array('error'=&gt;'Sorry, only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp; PNG files are allowed to upload.'); 
111    } 
112} 
113
114if($uploadStatus == 1){ 
115    //Add to database
116}
117

Uploading will work if submit the form directly from PHP. I've looked through and compared apache and php configurations to check if there is anything missing. Below are the server configurations of apache and php. Uploading works in both Server1 and Server2.

Server 1:

1&lt;form id=&quot;gal-form&quot; class=&quot;form-gallery&quot; enctype=&quot;multipart/form-data&quot;&gt;
2    &lt;input type=&quot;hidden&quot; id=&quot;gal_id&quot; name=&quot;id&quot; value=&quot;&quot;&gt;
3    &lt;div class=&quot;up-types&quot;&gt;
4        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
5            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
6            &lt;input type=&quot;text&quot; value=&quot;ebooks&quot; disabled=&quot;&quot;&gt;
7            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;ebooks&quot; id=&quot;links_to_3&quot; value=&quot;&quot;&gt;
8        &lt;/div&gt;
9        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
10            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
11            &lt;input type=&quot;text&quot; value=&quot;handbooks&quot; disabled=&quot;&quot;&gt;
12            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;handbooks&quot; id=&quot;links_to_4&quot; value=&quot;&quot;&gt;
13        &lt;/div&gt;
14        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
15            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
16            &lt;input type=&quot;text&quot; value=&quot;manuals&quot; disabled=&quot;&quot;&gt;
17            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;manuals&quot; id=&quot;links_to_5&quot; value=&quot;&quot;&gt;
18        &lt;/div&gt;
19    &lt;/div&gt;
20    &lt;div class=&quot;form-group&quot;&gt;
21        &lt;label for=&quot;gal_title&quot;&gt;Title&lt;/label&gt;
22        &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;gal_title&quot; name=&quot;title&quot; placeholder=&quot;Add a title here..&quot;&gt;
23    &lt;/div&gt;
24    &lt;div class=&quot;form-group&quot;&gt;
25        &lt;label for=&quot;gal_title&quot;&gt;Category&lt;/label&gt;
26        &lt;input id=&quot;gallery_tags&quot; class=&quot;form-control&quot; name=&quot;tags[]&quot; type=&quot;text&quot; value=&quot;&quot; placeholder=&quot;Add a category here..&quot;&gt;
27    &lt;/div&gt;
28    &lt;div class=&quot;form-group&quot;&gt;
29        &lt;label&gt;File upload &lt;span class=&quot;text-danger&quot;&gt;*Only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp;amp; PNG files are allowed. Please try to upload images/videos of a specific aspect ratio&lt;/span&gt;&lt;/label&gt;
30        &lt;input type=&quot;file&quot; name=&quot;gal&quot; id=&quot;gal-file&quot; class=&quot;file-upload-default&quot;&gt;
31        &lt;div class=&quot;input-group col-xs-12&quot;&gt;
32            &lt;input type=&quot;text&quot; class=&quot;form-control file-upload-info&quot; disabled=&quot;&quot; placeholder=&quot;Upload File&quot;&gt;
33            &lt;span class=&quot;input-group-append&quot;&gt;
34                &lt;button class=&quot;file-upload-browse btn btn-primary&quot; type=&quot;button&quot;&gt;Browse&lt;/button&gt;
35            &lt;/span&gt;
36        &lt;/div&gt;
37    &lt;/div&gt;
38    &lt;div class=&quot;form-group&quot;&gt;
39        &lt;label for=&quot;event_text&quot;&gt;Description&lt;/label&gt;
40        &lt;textarea class=&quot;form-control&quot; id=&quot;media_desc&quot; name=&quot;desc&quot; rows=&quot;4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/textarea&gt;
41    &lt;/div&gt;
42    &lt;button type=&quot;submit&quot; id=&quot;gal-button&quot; class=&quot;btn btn-primary mr-2&quot;&gt;Submit&lt;/button&gt;
43&lt;/form&gt;
44$(&quot;#gal-form&quot;).on('submit', function(e) {
45    e.preventDefault();
46    var desc = &quot;Some description here&quot;;
47
48    if ($('#gal_title').val() == '') {
49        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter title name...&lt;/span&gt;');
50        return false;
51    } else if ($('#gal-file').get(0).files.length === 0 &amp;&amp; !desc) {
52        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter a description or choose a file to upload...&lt;/span&gt;');
53        return false;
54    } 
55
56    var formData = new FormData(this);
57    var values = $(&quot;input[name='links[]']:enabled&quot;).map(function() {
58        let id = this.id.split(&quot;_&quot;).pop();
59        let link = $(this).data(&quot;type&quot;);
60        if (this.value) {
61            link += &quot;/&quot; + this.value;
62        }
63        return {
64            id: id,
65            link: link
66        };
67    }).get();
68    formData.append('links_to', JSON.stringify(values));
69    formData.set('desc',desc);
70
71    $.ajax({
72        type: 'POST',
73        url: 'url',
74        data: formData,
75        dataType: 'json',
76        contentType: false,
77        cache: false,
78        processData: false,
79        success: function(obj) {
80            if (obj.success) {
81                window.location.reload();
82            } else {
83                alertItem(obj.error);
84            }
85        },
86        error: function(request, status, error) {
87            alertItem(request.responseText);
88        }
89    });
90});
91$uploadStatus = 1; 
92$data = array();
93if(!empty($_FILES[&quot;gal&quot;][&quot;name&quot;])){ 
94    $file_name = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]),PATHINFO_FILENAME);
95    $fileType = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]), PATHINFO_EXTENSION);
96
97    $fileName = $this-&gt;generateSlug($file_name).'_'.time().'.'.$fileType; 
98    $targetFilePath = $fileName; 
99        
100    $allowTypes = array('pdf', 'mp4', 'webm', 'ogg', 'jpg', 'png', 'jpeg'); 
101    if(in_array(strtolower($fileType), $allowTypes)){ 
102        if(move_uploaded_file($_FILES[&quot;gal&quot;][&quot;tmp_name&quot;], $targetFilePath)){ 
103            $data['file'] = $fileName;
104        }else{ 
105            $uploadStatus = 0; 
106            return  array('error'=&gt;$_FILES[&quot;error&quot;])); 
107        } 
108    }else{ 
109        $uploadStatus = 0; 
110        return  array('error'=&gt;'Sorry, only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp; PNG files are allowed to upload.'); 
111    } 
112} 
113
114if($uploadStatus == 1){ 
115    //Add to database
116}
117Apache/2.4.6 (RHEL 7.9)
118PHP 7.3.29
119

Server 2:

1&lt;form id=&quot;gal-form&quot; class=&quot;form-gallery&quot; enctype=&quot;multipart/form-data&quot;&gt;
2    &lt;input type=&quot;hidden&quot; id=&quot;gal_id&quot; name=&quot;id&quot; value=&quot;&quot;&gt;
3    &lt;div class=&quot;up-types&quot;&gt;
4        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
5            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
6            &lt;input type=&quot;text&quot; value=&quot;ebooks&quot; disabled=&quot;&quot;&gt;
7            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;ebooks&quot; id=&quot;links_to_3&quot; value=&quot;&quot;&gt;
8        &lt;/div&gt;
9        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
10            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
11            &lt;input type=&quot;text&quot; value=&quot;handbooks&quot; disabled=&quot;&quot;&gt;
12            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;handbooks&quot; id=&quot;links_to_4&quot; value=&quot;&quot;&gt;
13        &lt;/div&gt;
14        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
15            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
16            &lt;input type=&quot;text&quot; value=&quot;manuals&quot; disabled=&quot;&quot;&gt;
17            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;manuals&quot; id=&quot;links_to_5&quot; value=&quot;&quot;&gt;
18        &lt;/div&gt;
19    &lt;/div&gt;
20    &lt;div class=&quot;form-group&quot;&gt;
21        &lt;label for=&quot;gal_title&quot;&gt;Title&lt;/label&gt;
22        &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;gal_title&quot; name=&quot;title&quot; placeholder=&quot;Add a title here..&quot;&gt;
23    &lt;/div&gt;
24    &lt;div class=&quot;form-group&quot;&gt;
25        &lt;label for=&quot;gal_title&quot;&gt;Category&lt;/label&gt;
26        &lt;input id=&quot;gallery_tags&quot; class=&quot;form-control&quot; name=&quot;tags[]&quot; type=&quot;text&quot; value=&quot;&quot; placeholder=&quot;Add a category here..&quot;&gt;
27    &lt;/div&gt;
28    &lt;div class=&quot;form-group&quot;&gt;
29        &lt;label&gt;File upload &lt;span class=&quot;text-danger&quot;&gt;*Only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp;amp; PNG files are allowed. Please try to upload images/videos of a specific aspect ratio&lt;/span&gt;&lt;/label&gt;
30        &lt;input type=&quot;file&quot; name=&quot;gal&quot; id=&quot;gal-file&quot; class=&quot;file-upload-default&quot;&gt;
31        &lt;div class=&quot;input-group col-xs-12&quot;&gt;
32            &lt;input type=&quot;text&quot; class=&quot;form-control file-upload-info&quot; disabled=&quot;&quot; placeholder=&quot;Upload File&quot;&gt;
33            &lt;span class=&quot;input-group-append&quot;&gt;
34                &lt;button class=&quot;file-upload-browse btn btn-primary&quot; type=&quot;button&quot;&gt;Browse&lt;/button&gt;
35            &lt;/span&gt;
36        &lt;/div&gt;
37    &lt;/div&gt;
38    &lt;div class=&quot;form-group&quot;&gt;
39        &lt;label for=&quot;event_text&quot;&gt;Description&lt;/label&gt;
40        &lt;textarea class=&quot;form-control&quot; id=&quot;media_desc&quot; name=&quot;desc&quot; rows=&quot;4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/textarea&gt;
41    &lt;/div&gt;
42    &lt;button type=&quot;submit&quot; id=&quot;gal-button&quot; class=&quot;btn btn-primary mr-2&quot;&gt;Submit&lt;/button&gt;
43&lt;/form&gt;
44$(&quot;#gal-form&quot;).on('submit', function(e) {
45    e.preventDefault();
46    var desc = &quot;Some description here&quot;;
47
48    if ($('#gal_title').val() == '') {
49        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter title name...&lt;/span&gt;');
50        return false;
51    } else if ($('#gal-file').get(0).files.length === 0 &amp;&amp; !desc) {
52        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter a description or choose a file to upload...&lt;/span&gt;');
53        return false;
54    } 
55
56    var formData = new FormData(this);
57    var values = $(&quot;input[name='links[]']:enabled&quot;).map(function() {
58        let id = this.id.split(&quot;_&quot;).pop();
59        let link = $(this).data(&quot;type&quot;);
60        if (this.value) {
61            link += &quot;/&quot; + this.value;
62        }
63        return {
64            id: id,
65            link: link
66        };
67    }).get();
68    formData.append('links_to', JSON.stringify(values));
69    formData.set('desc',desc);
70
71    $.ajax({
72        type: 'POST',
73        url: 'url',
74        data: formData,
75        dataType: 'json',
76        contentType: false,
77        cache: false,
78        processData: false,
79        success: function(obj) {
80            if (obj.success) {
81                window.location.reload();
82            } else {
83                alertItem(obj.error);
84            }
85        },
86        error: function(request, status, error) {
87            alertItem(request.responseText);
88        }
89    });
90});
91$uploadStatus = 1; 
92$data = array();
93if(!empty($_FILES[&quot;gal&quot;][&quot;name&quot;])){ 
94    $file_name = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]),PATHINFO_FILENAME);
95    $fileType = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]), PATHINFO_EXTENSION);
96
97    $fileName = $this-&gt;generateSlug($file_name).'_'.time().'.'.$fileType; 
98    $targetFilePath = $fileName; 
99        
100    $allowTypes = array('pdf', 'mp4', 'webm', 'ogg', 'jpg', 'png', 'jpeg'); 
101    if(in_array(strtolower($fileType), $allowTypes)){ 
102        if(move_uploaded_file($_FILES[&quot;gal&quot;][&quot;tmp_name&quot;], $targetFilePath)){ 
103            $data['file'] = $fileName;
104        }else{ 
105            $uploadStatus = 0; 
106            return  array('error'=&gt;$_FILES[&quot;error&quot;])); 
107        } 
108    }else{ 
109        $uploadStatus = 0; 
110        return  array('error'=&gt;'Sorry, only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp; PNG files are allowed to upload.'); 
111    } 
112} 
113
114if($uploadStatus == 1){ 
115    //Add to database
116}
117Apache/2.4.6 (RHEL 7.9)
118PHP 7.3.29
119Apache/2.4.37 (RHEL 8.4)
120PHP 7.4.19
121

Server 3 (New Server):

1&lt;form id=&quot;gal-form&quot; class=&quot;form-gallery&quot; enctype=&quot;multipart/form-data&quot;&gt;
2    &lt;input type=&quot;hidden&quot; id=&quot;gal_id&quot; name=&quot;id&quot; value=&quot;&quot;&gt;
3    &lt;div class=&quot;up-types&quot;&gt;
4        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
5            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
6            &lt;input type=&quot;text&quot; value=&quot;ebooks&quot; disabled=&quot;&quot;&gt;
7            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;ebooks&quot; id=&quot;links_to_3&quot; value=&quot;&quot;&gt;
8        &lt;/div&gt;
9        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
10            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
11            &lt;input type=&quot;text&quot; value=&quot;handbooks&quot; disabled=&quot;&quot;&gt;
12            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;handbooks&quot; id=&quot;links_to_4&quot; value=&quot;&quot;&gt;
13        &lt;/div&gt;
14        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
15            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
16            &lt;input type=&quot;text&quot; value=&quot;manuals&quot; disabled=&quot;&quot;&gt;
17            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;manuals&quot; id=&quot;links_to_5&quot; value=&quot;&quot;&gt;
18        &lt;/div&gt;
19    &lt;/div&gt;
20    &lt;div class=&quot;form-group&quot;&gt;
21        &lt;label for=&quot;gal_title&quot;&gt;Title&lt;/label&gt;
22        &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;gal_title&quot; name=&quot;title&quot; placeholder=&quot;Add a title here..&quot;&gt;
23    &lt;/div&gt;
24    &lt;div class=&quot;form-group&quot;&gt;
25        &lt;label for=&quot;gal_title&quot;&gt;Category&lt;/label&gt;
26        &lt;input id=&quot;gallery_tags&quot; class=&quot;form-control&quot; name=&quot;tags[]&quot; type=&quot;text&quot; value=&quot;&quot; placeholder=&quot;Add a category here..&quot;&gt;
27    &lt;/div&gt;
28    &lt;div class=&quot;form-group&quot;&gt;
29        &lt;label&gt;File upload &lt;span class=&quot;text-danger&quot;&gt;*Only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp;amp; PNG files are allowed. Please try to upload images/videos of a specific aspect ratio&lt;/span&gt;&lt;/label&gt;
30        &lt;input type=&quot;file&quot; name=&quot;gal&quot; id=&quot;gal-file&quot; class=&quot;file-upload-default&quot;&gt;
31        &lt;div class=&quot;input-group col-xs-12&quot;&gt;
32            &lt;input type=&quot;text&quot; class=&quot;form-control file-upload-info&quot; disabled=&quot;&quot; placeholder=&quot;Upload File&quot;&gt;
33            &lt;span class=&quot;input-group-append&quot;&gt;
34                &lt;button class=&quot;file-upload-browse btn btn-primary&quot; type=&quot;button&quot;&gt;Browse&lt;/button&gt;
35            &lt;/span&gt;
36        &lt;/div&gt;
37    &lt;/div&gt;
38    &lt;div class=&quot;form-group&quot;&gt;
39        &lt;label for=&quot;event_text&quot;&gt;Description&lt;/label&gt;
40        &lt;textarea class=&quot;form-control&quot; id=&quot;media_desc&quot; name=&quot;desc&quot; rows=&quot;4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/textarea&gt;
41    &lt;/div&gt;
42    &lt;button type=&quot;submit&quot; id=&quot;gal-button&quot; class=&quot;btn btn-primary mr-2&quot;&gt;Submit&lt;/button&gt;
43&lt;/form&gt;
44$(&quot;#gal-form&quot;).on('submit', function(e) {
45    e.preventDefault();
46    var desc = &quot;Some description here&quot;;
47
48    if ($('#gal_title').val() == '') {
49        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter title name...&lt;/span&gt;');
50        return false;
51    } else if ($('#gal-file').get(0).files.length === 0 &amp;&amp; !desc) {
52        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter a description or choose a file to upload...&lt;/span&gt;');
53        return false;
54    } 
55
56    var formData = new FormData(this);
57    var values = $(&quot;input[name='links[]']:enabled&quot;).map(function() {
58        let id = this.id.split(&quot;_&quot;).pop();
59        let link = $(this).data(&quot;type&quot;);
60        if (this.value) {
61            link += &quot;/&quot; + this.value;
62        }
63        return {
64            id: id,
65            link: link
66        };
67    }).get();
68    formData.append('links_to', JSON.stringify(values));
69    formData.set('desc',desc);
70
71    $.ajax({
72        type: 'POST',
73        url: 'url',
74        data: formData,
75        dataType: 'json',
76        contentType: false,
77        cache: false,
78        processData: false,
79        success: function(obj) {
80            if (obj.success) {
81                window.location.reload();
82            } else {
83                alertItem(obj.error);
84            }
85        },
86        error: function(request, status, error) {
87            alertItem(request.responseText);
88        }
89    });
90});
91$uploadStatus = 1; 
92$data = array();
93if(!empty($_FILES[&quot;gal&quot;][&quot;name&quot;])){ 
94    $file_name = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]),PATHINFO_FILENAME);
95    $fileType = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]), PATHINFO_EXTENSION);
96
97    $fileName = $this-&gt;generateSlug($file_name).'_'.time().'.'.$fileType; 
98    $targetFilePath = $fileName; 
99        
100    $allowTypes = array('pdf', 'mp4', 'webm', 'ogg', 'jpg', 'png', 'jpeg'); 
101    if(in_array(strtolower($fileType), $allowTypes)){ 
102        if(move_uploaded_file($_FILES[&quot;gal&quot;][&quot;tmp_name&quot;], $targetFilePath)){ 
103            $data['file'] = $fileName;
104        }else{ 
105            $uploadStatus = 0; 
106            return  array('error'=&gt;$_FILES[&quot;error&quot;])); 
107        } 
108    }else{ 
109        $uploadStatus = 0; 
110        return  array('error'=&gt;'Sorry, only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp; PNG files are allowed to upload.'); 
111    } 
112} 
113
114if($uploadStatus == 1){ 
115    //Add to database
116}
117Apache/2.4.6 (RHEL 7.9)
118PHP 7.3.29
119Apache/2.4.37 (RHEL 8.4)
120PHP 7.4.19
121Apache/2.4.46 (RHEL 7.9)
122PHP 7.4.12
123

I tried to close the connection by setting header("Connection: close");, increased max_upload_size, post_max_size but no use.

What could be a possible reason for this?

Sample payload is also given below:

1&lt;form id=&quot;gal-form&quot; class=&quot;form-gallery&quot; enctype=&quot;multipart/form-data&quot;&gt;
2    &lt;input type=&quot;hidden&quot; id=&quot;gal_id&quot; name=&quot;id&quot; value=&quot;&quot;&gt;
3    &lt;div class=&quot;up-types&quot;&gt;
4        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
5            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
6            &lt;input type=&quot;text&quot; value=&quot;ebooks&quot; disabled=&quot;&quot;&gt;
7            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;ebooks&quot; id=&quot;links_to_3&quot; value=&quot;&quot;&gt;
8        &lt;/div&gt;
9        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
10            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
11            &lt;input type=&quot;text&quot; value=&quot;handbooks&quot; disabled=&quot;&quot;&gt;
12            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;handbooks&quot; id=&quot;links_to_4&quot; value=&quot;&quot;&gt;
13        &lt;/div&gt;
14        &lt;div class=&quot;input-group mb-3 display-none check-links&quot;&gt;
15            &lt;span class=&quot;input-group-text&quot;&gt;Links to&lt;/span&gt;
16            &lt;input type=&quot;text&quot; value=&quot;manuals&quot; disabled=&quot;&quot;&gt;
17            &lt;input type=&quot;text&quot; name=&quot;links[]&quot; class=&quot;form-control&quot; data-type=&quot;manuals&quot; id=&quot;links_to_5&quot; value=&quot;&quot;&gt;
18        &lt;/div&gt;
19    &lt;/div&gt;
20    &lt;div class=&quot;form-group&quot;&gt;
21        &lt;label for=&quot;gal_title&quot;&gt;Title&lt;/label&gt;
22        &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;gal_title&quot; name=&quot;title&quot; placeholder=&quot;Add a title here..&quot;&gt;
23    &lt;/div&gt;
24    &lt;div class=&quot;form-group&quot;&gt;
25        &lt;label for=&quot;gal_title&quot;&gt;Category&lt;/label&gt;
26        &lt;input id=&quot;gallery_tags&quot; class=&quot;form-control&quot; name=&quot;tags[]&quot; type=&quot;text&quot; value=&quot;&quot; placeholder=&quot;Add a category here..&quot;&gt;
27    &lt;/div&gt;
28    &lt;div class=&quot;form-group&quot;&gt;
29        &lt;label&gt;File upload &lt;span class=&quot;text-danger&quot;&gt;*Only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp;amp; PNG files are allowed. Please try to upload images/videos of a specific aspect ratio&lt;/span&gt;&lt;/label&gt;
30        &lt;input type=&quot;file&quot; name=&quot;gal&quot; id=&quot;gal-file&quot; class=&quot;file-upload-default&quot;&gt;
31        &lt;div class=&quot;input-group col-xs-12&quot;&gt;
32            &lt;input type=&quot;text&quot; class=&quot;form-control file-upload-info&quot; disabled=&quot;&quot; placeholder=&quot;Upload File&quot;&gt;
33            &lt;span class=&quot;input-group-append&quot;&gt;
34                &lt;button class=&quot;file-upload-browse btn btn-primary&quot; type=&quot;button&quot;&gt;Browse&lt;/button&gt;
35            &lt;/span&gt;
36        &lt;/div&gt;
37    &lt;/div&gt;
38    &lt;div class=&quot;form-group&quot;&gt;
39        &lt;label for=&quot;event_text&quot;&gt;Description&lt;/label&gt;
40        &lt;textarea class=&quot;form-control&quot; id=&quot;media_desc&quot; name=&quot;desc&quot; rows=&quot;4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/textarea&gt;
41    &lt;/div&gt;
42    &lt;button type=&quot;submit&quot; id=&quot;gal-button&quot; class=&quot;btn btn-primary mr-2&quot;&gt;Submit&lt;/button&gt;
43&lt;/form&gt;
44$(&quot;#gal-form&quot;).on('submit', function(e) {
45    e.preventDefault();
46    var desc = &quot;Some description here&quot;;
47
48    if ($('#gal_title').val() == '') {
49        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter title name...&lt;/span&gt;');
50        return false;
51    } else if ($('#gal-file').get(0).files.length === 0 &amp;&amp; !desc) {
52        $('#display-msg').html('&lt;span style=&quot;color:red&quot;&gt;Please enter a description or choose a file to upload...&lt;/span&gt;');
53        return false;
54    } 
55
56    var formData = new FormData(this);
57    var values = $(&quot;input[name='links[]']:enabled&quot;).map(function() {
58        let id = this.id.split(&quot;_&quot;).pop();
59        let link = $(this).data(&quot;type&quot;);
60        if (this.value) {
61            link += &quot;/&quot; + this.value;
62        }
63        return {
64            id: id,
65            link: link
66        };
67    }).get();
68    formData.append('links_to', JSON.stringify(values));
69    formData.set('desc',desc);
70
71    $.ajax({
72        type: 'POST',
73        url: 'url',
74        data: formData,
75        dataType: 'json',
76        contentType: false,
77        cache: false,
78        processData: false,
79        success: function(obj) {
80            if (obj.success) {
81                window.location.reload();
82            } else {
83                alertItem(obj.error);
84            }
85        },
86        error: function(request, status, error) {
87            alertItem(request.responseText);
88        }
89    });
90});
91$uploadStatus = 1; 
92$data = array();
93if(!empty($_FILES[&quot;gal&quot;][&quot;name&quot;])){ 
94    $file_name = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]),PATHINFO_FILENAME);
95    $fileType = pathinfo(basename($_FILES[&quot;gal&quot;][&quot;name&quot;]), PATHINFO_EXTENSION);
96
97    $fileName = $this-&gt;generateSlug($file_name).'_'.time().'.'.$fileType; 
98    $targetFilePath = $fileName; 
99        
100    $allowTypes = array('pdf', 'mp4', 'webm', 'ogg', 'jpg', 'png', 'jpeg'); 
101    if(in_array(strtolower($fileType), $allowTypes)){ 
102        if(move_uploaded_file($_FILES[&quot;gal&quot;][&quot;tmp_name&quot;], $targetFilePath)){ 
103            $data['file'] = $fileName;
104        }else{ 
105            $uploadStatus = 0; 
106            return  array('error'=&gt;$_FILES[&quot;error&quot;])); 
107        } 
108    }else{ 
109        $uploadStatus = 0; 
110        return  array('error'=&gt;'Sorry, only PDF, MP4, WEBM, OGG, JPG, JPEG, &amp; PNG files are allowed to upload.'); 
111    } 
112} 
113
114if($uploadStatus == 1){ 
115    //Add to database
116}
117Apache/2.4.6 (RHEL 7.9)
118PHP 7.3.29
119Apache/2.4.37 (RHEL 8.4)
120PHP 7.4.19
121Apache/2.4.46 (RHEL 7.9)
122PHP 7.4.12
123------WebKitFormBoundaryj7GC6KVa5gPA46RP
124Content-Disposition: form-data; name=&quot;id&quot;
125
126
127------WebKitFormBoundaryj7GC6KVa5gPA46RP
128Content-Disposition: form-data; name=&quot;category[]&quot;
129
1301
131------WebKitFormBoundaryj7GC6KVa5gPA46RP
132Content-Disposition: form-data; name=&quot;links[]&quot;
133
134
135------WebKitFormBoundaryj7GC6KVa5gPA46RP
136Content-Disposition: form-data; name=&quot;title&quot;
137
138Test
139------WebKitFormBoundaryj7GC6KVa5gPA46RP
140Content-Disposition: form-data; name=&quot;tags[]&quot;
141
142Cat
143------WebKitFormBoundaryj7GC6KVa5gPA46RP
144Content-Disposition: form-data; name=&quot;gal&quot;; filename=&quot;not.png&quot;
145Content-Type: image/png
146
147
148------WebKitFormBoundaryj7GC6KVa5gPA46RP
149Content-Disposition: form-data; name=&quot;desc&quot;
150
151&lt;p&gt;Test description&lt;/p&gt;
152------WebKitFormBoundaryj7GC6KVa5gPA46RP
153Content-Disposition: form-data; name=&quot;links_to&quot;
154
155[{&quot;id&quot;:&quot;1&quot;,&quot;link&quot;:&quot;photo&quot;}]
156------WebKitFormBoundaryj7GC6KVa5gPA46RP--
157

ANSWER

Answered 2022-Mar-02 at 11:40

I recently found that the problem is due to Mod Security rules in the server. I've disabled Mod Security by setting SecRuleEngine Off in modesecurity.conf, though it is not a good solution. Please update if anyone knows how to do this without turning off this module.

Source https://stackoverflow.com/questions/71318362

QUESTION

How to get data point label using click in plotly

Asked 2022-Feb-14 at 19:11

I would like to store the data point label whenever I click it in my plotly plot. The label is the name of the data point that appears in the first column of my data frame.

For example if I hover over a data point it will show me the x and y information as well as the data point name: x: TRUE y: 27 Name: cheeseburger

What I want is to store the label of that data point, 'cheeseburger' as a variable to use later.

I have tried using plotly_click and accessing the event_data but it returns x and y values and all I want is the data point name. This is my code:

1
2    library(shiny)
3    library(plotly)
4    
5ui &lt;- navbarPage(fluid = TRUE, id = &quot;navbarID&quot;,
6  theme = shinytheme(&quot;superhero&quot;),
7  tabsetPanel(type = &quot;tabs&quot;,
8  tabPanel(&quot;File Upload&quot;,
9
10  # Sidebar layout with input and output definitions ----
11  sidebarLayout(
12
13    # Sidebar panel for inputs ----
14    sidebarPanel(
15
16      # Input: Select a file ----
17      fileInput(&quot;file1&quot;, &quot;Choose CSV File&quot;,
18                multiple = FALSE,
19                accept = c(&quot;text/csv&quot;,
20                         &quot;text/comma-separated-values,text/plain&quot;,
21                         &quot;.csv&quot;)),
22
23      # Horizontal line ----
24      tags$hr(),
25
26      # Input: Checkbox if file has header ----
27      checkboxInput(&quot;header&quot;, &quot;Header&quot;, TRUE),
28
29      # Input: Select separator ----
30      radioButtons(&quot;sep&quot;, &quot;Separator&quot;,
31                   choices = c(Comma = &quot;,&quot;,
32                               Semicolon = &quot;;&quot;,
33                               Tab = &quot;\t&quot;),
34                   selected = &quot;,&quot;),
35
36      # Input: Select quotes ----
37      radioButtons(&quot;quote&quot;, &quot;Quote&quot;,
38                   choices = c(None = &quot;&quot;,
39                               &quot;Double Quote&quot; = '&quot;',
40                               &quot;Single Quote&quot; = &quot;'&quot;),
41                   selected = '&quot;'),
42
43      # Horizontal line ----
44      tags$hr(),
45
46      # Input: Select number of rows to display ----
47      radioButtons(&quot;disp&quot;, &quot;Display&quot;,
48                   choices = c(Head = &quot;head&quot;,
49                               All = &quot;all&quot;),
50                   selected = &quot;head&quot;)
51
52    ),
53
54   
55     mainPanel(
56
57      # Output: Data file ----
58      tableOutput(&quot;contents&quot;)
59
60    ),
61    
62  )  
63  ),   
64 tabPanel(&quot;firstbox&quot;, 
65 uiOutput(&quot;box&quot;),
66 
67),
68    tabPanel(&quot;facet_plots&quot;,
69    mainPanel(plotlyOutput(&quot;ind_plot&quot;))
70    )    # Main panel for displaying outputs ----
71))
72
73
74# server ----
75# Define server logic to plot various variables against 
76server &lt;- function(input, output, session) {
77  
78  
79  my_data &lt;- reactive({
80    
81  inFile &lt;- input$file1
82    req(inFile)
83
84    # when reading semicolon separated files,
85    # having a comma separator causes `read.csv` to error
86    tryCatch(
87      {
88        df_x &lt;&lt;- read.csv(inFile$datapath,
89                 header = input$header,
90                 sep = input$sep,
91                 quote = input$quote)
92       
93      },
94      error = function(e) {
95        # return a safeError if a parsing error occurs
96        stop(safeError(e))
97      }
98    )
99
100    if(input$disp == &quot;head&quot;) {
101      return(head(df_x))
102    }
103    else {
104      return(df_x)
105    } 
106
107    })
108
109  #server logic for file upload tab
110   output$contents &lt;- renderTable({
111     my_data()
112
113  })
114
115  
116  
117  #server logic for boxplot tab
118  output$box &lt;- renderUI({
119   tabPanel(&quot;first_box&quot;, 
120  sidebarPanel(
121    selectInput(&quot;variable&quot;, &quot;Name:&quot;, unique(qc$Action)),
122    sliderInput(&quot;quantile&quot;, &quot;Quantile Range:&quot;,
123      min = 75, max = 95, value = c(85), step = 5),
124    br(),
125    br(),
126  
127mainPanel(
128    h2(&quot;title&quot;, align = &quot;center&quot;),
129plotlyOutput(&quot;plot&quot;, height = '1000px', width = &quot;100%&quot;)
130           )
131
132)
133    
134    })
135    
136
137  observeEvent(input$file1, {
138    req(df_x)
139    source(&quot;db_prep.R&quot;)
140
141  
142  fn &lt;- reactive(get(paste0(&quot;s_&quot;, input$quantile)))
143  output$plot &lt;-  renderPlotly(fn()(input$variable))
144})                        #    ^^^ note the reactive value goes fn()(var)
145
146  
147 
148     
149  s_75 &lt;- function(var) box_75(var) 
150  s_80 &lt;- function(var) box_80(var) 
151  s_85 &lt;- function(var) box_85(var) 
152  s_90 &lt;- function(var) box_90(var)
153  s_95 &lt;- function(var) box_95(var)
154  m_p &lt;-  function(var) com_g(var)
155
156  
157 #Below is that part I am running into trouble
158  
159  #create reactive for subset plot on second tab
160    observeEvent(input$variable, {
161    s &lt;- reactive({
162    event_data(&quot;plotly_click&quot;,  source = 'sub_plot')
163    })
164
165    
166  observeEvent(s(), {
167    updateTabsetPanel(session, inputId = &quot;navbarID&quot;, selected = &quot;facet_plots&quot;)
168  })
169
170    output$ind_plot &lt;- renderPlotly({
171    req(s())
172    
173    m_p(s()) # &lt;-- problem here. I need to feed data point label as a string into this function to transform and render new sub plot. 
174  })
175    
176  })
177
178

ANSWER

Answered 2022-Feb-14 at 19:11

Updated based on OP's comment that the label for each point is placed using geom_text(label()) and converted to plotly object

1
2    library(shiny)
3    library(plotly)
4    
5ui &lt;- navbarPage(fluid = TRUE, id = &quot;navbarID&quot;,
6  theme = shinytheme(&quot;superhero&quot;),
7  tabsetPanel(type = &quot;tabs&quot;,
8  tabPanel(&quot;File Upload&quot;,
9
10  # Sidebar layout with input and output definitions ----
11  sidebarLayout(
12
13    # Sidebar panel for inputs ----
14    sidebarPanel(
15
16      # Input: Select a file ----
17      fileInput(&quot;file1&quot;, &quot;Choose CSV File&quot;,
18                multiple = FALSE,
19                accept = c(&quot;text/csv&quot;,
20                         &quot;text/comma-separated-values,text/plain&quot;,
21                         &quot;.csv&quot;)),
22
23      # Horizontal line ----
24      tags$hr(),
25
26      # Input: Checkbox if file has header ----
27      checkboxInput(&quot;header&quot;, &quot;Header&quot;, TRUE),
28
29      # Input: Select separator ----
30      radioButtons(&quot;sep&quot;, &quot;Separator&quot;,
31                   choices = c(Comma = &quot;,&quot;,
32                               Semicolon = &quot;;&quot;,
33                               Tab = &quot;\t&quot;),
34                   selected = &quot;,&quot;),
35
36      # Input: Select quotes ----
37      radioButtons(&quot;quote&quot;, &quot;Quote&quot;,
38                   choices = c(None = &quot;&quot;,
39                               &quot;Double Quote&quot; = '&quot;',
40                               &quot;Single Quote&quot; = &quot;'&quot;),
41                   selected = '&quot;'),
42
43      # Horizontal line ----
44      tags$hr(),
45
46      # Input: Select number of rows to display ----
47      radioButtons(&quot;disp&quot;, &quot;Display&quot;,
48                   choices = c(Head = &quot;head&quot;,
49                               All = &quot;all&quot;),
50                   selected = &quot;head&quot;)
51
52    ),
53
54   
55     mainPanel(
56
57      # Output: Data file ----
58      tableOutput(&quot;contents&quot;)
59
60    ),
61    
62  )  
63  ),   
64 tabPanel(&quot;firstbox&quot;, 
65 uiOutput(&quot;box&quot;),
66 
67),
68    tabPanel(&quot;facet_plots&quot;,
69    mainPanel(plotlyOutput(&quot;ind_plot&quot;))
70    )    # Main panel for displaying outputs ----
71))
72
73
74# server ----
75# Define server logic to plot various variables against 
76server &lt;- function(input, output, session) {
77  
78  
79  my_data &lt;- reactive({
80    
81  inFile &lt;- input$file1
82    req(inFile)
83
84    # when reading semicolon separated files,
85    # having a comma separator causes `read.csv` to error
86    tryCatch(
87      {
88        df_x &lt;&lt;- read.csv(inFile$datapath,
89                 header = input$header,
90                 sep = input$sep,
91                 quote = input$quote)
92       
93      },
94      error = function(e) {
95        # return a safeError if a parsing error occurs
96        stop(safeError(e))
97      }
98    )
99
100    if(input$disp == &quot;head&quot;) {
101      return(head(df_x))
102    }
103    else {
104      return(df_x)
105    } 
106
107    })
108
109  #server logic for file upload tab
110   output$contents &lt;- renderTable({
111     my_data()
112
113  })
114
115  
116  
117  #server logic for boxplot tab
118  output$box &lt;- renderUI({
119   tabPanel(&quot;first_box&quot;, 
120  sidebarPanel(
121    selectInput(&quot;variable&quot;, &quot;Name:&quot;, unique(qc$Action)),
122    sliderInput(&quot;quantile&quot;, &quot;Quantile Range:&quot;,
123      min = 75, max = 95, value = c(85), step = 5),
124    br(),
125    br(),
126  
127mainPanel(
128    h2(&quot;title&quot;, align = &quot;center&quot;),
129plotlyOutput(&quot;plot&quot;, height = '1000px', width = &quot;100%&quot;)
130           )
131
132)
133    
134    })
135    
136
137  observeEvent(input$file1, {
138    req(df_x)
139    source(&quot;db_prep.R&quot;)
140
141  
142  fn &lt;- reactive(get(paste0(&quot;s_&quot;, input$quantile)))
143  output$plot &lt;-  renderPlotly(fn()(input$variable))
144})                        #    ^^^ note the reactive value goes fn()(var)
145
146  
147 
148     
149  s_75 &lt;- function(var) box_75(var) 
150  s_80 &lt;- function(var) box_80(var) 
151  s_85 &lt;- function(var) box_85(var) 
152  s_90 &lt;- function(var) box_90(var)
153  s_95 &lt;- function(var) box_95(var)
154  m_p &lt;-  function(var) com_g(var)
155
156  
157 #Below is that part I am running into trouble
158  
159  #create reactive for subset plot on second tab
160    observeEvent(input$variable, {
161    s &lt;- reactive({
162    event_data(&quot;plotly_click&quot;,  source = 'sub_plot')
163    })
164
165    
166  observeEvent(s(), {
167    updateTabsetPanel(session, inputId = &quot;navbarID&quot;, selected = &quot;facet_plots&quot;)
168  })
169
170    output$ind_plot &lt;- renderPlotly({
171    req(s())
172    
173    m_p(s()) # &lt;-- problem here. I need to feed data point label as a string into this function to transform and render new sub plot. 
174  })
175    
176  })
177
178library(shiny)
179library(plotly)
180library(data.table)
181
182data = data.table(x=1:10, y=sample(1:100, 10)) 
183food_labels = sample(c(&quot;cheeseburger&quot;, &quot;hamburger&quot;, &quot;salad&quot;, &quot;fries&quot;), 10, replace=T)
184
185get_plotly &lt;- function() {
186  ggplotly(ggplot(data,aes(x,y)) + geom_point() + geom_text(label=food_labels))
187}
188
189ui &lt;- fluidPage(
190  plotlyOutput(&quot;plot&quot;),
191  verbatimTextOutput(outputId = &quot;clicked_point&quot;)
192)
193
194server &lt;- function(input, output, session) {
195  
196  plt &lt;- reactive(get_plotly())
197  
198  output$plot &lt;- renderPlotly(plt())
199
200  s &lt;- reactive(event_data(&quot;plotly_click&quot;))
201  
202  label_name &lt;- eventReactive(s(), {
203    data.table(
204      x = plt()$x$data[[2]]$x,
205      y = plt()$x$data[[2]]$y,
206      text = plt()$x$data[[2]]$text
207      )[x==s()$x &amp; y==s()$y, text]
208  })
209  
210  output$clicked_point = renderPrint(label_name())
211}
212
213shinyApp(ui, server)
214

Source https://stackoverflow.com/questions/71096773

QUESTION

How to upload a stream to S3 with AWS SDK v3

Asked 2022-Feb-12 at 01:22

I have to transfer a file from and API endpoint to two different bucket. The original upload is made using:

1curl -X PUT -F &quot;data=@sample&quot; &quot;http://localhost:3000/upload/1/1&quot;
2

The endpoint where the file is uploaded:

1curl -X PUT -F &quot;data=@sample&quot; &quot;http://localhost:3000/upload/1/1&quot;
2const PassThrough = require('stream').PassThrough;
3
4async function uploadFile (req, res) {
5  try {
6    const firstS3Stream = new PassThrough();
7    const secondS3Stream = new PassThrough();
8    req.pipe(firstS3Stream);
9    req.pipe(secondS3Stream);
10
11    await Promise.all([
12      uploadToFirstS3(firstS3Stream),
13      uploadToSecondS3(secondS3Stream),
14    ]);
15    return res.end();
16  } catch (err) {
17    console.log(err)
18    return res.status(500).send({ error: 'Unexpected error during file upload' });
19  }
20}
21

As you can see, I use two PassThrough streams, in order to duplicate the request stream into two readable streams, as suggested in this SO thread.

This piece of code remains unchanged, what is interesting here are the uploadToFirstS3 and uploadToSecondS3 functions. In this minimal example both do exactly the same thing with a different configuration, i will expend only one here.

What Works Well:

1curl -X PUT -F &quot;data=@sample&quot; &quot;http://localhost:3000/upload/1/1&quot;
2const PassThrough = require('stream').PassThrough;
3
4async function uploadFile (req, res) {
5  try {
6    const firstS3Stream = new PassThrough();
7    const secondS3Stream = new PassThrough();
8    req.pipe(firstS3Stream);
9    req.pipe(secondS3Stream);
10
11    await Promise.all([
12      uploadToFirstS3(firstS3Stream),
13      uploadToSecondS3(secondS3Stream),
14    ]);
15    return res.end();
16  } catch (err) {
17    console.log(err)
18    return res.status(500).send({ error: 'Unexpected error during file upload' });
19  }
20}
21const aws = require('aws-sdk');
22
23const s3 = new aws.S3({
24  accessKeyId: S3_API_KEY,
25  secretAccessKey: S3_API_SECRET,
26  region: S3_REGION,
27  signatureVersion: 'v4',
28});
29
30const uploadToFirstS3 = (stream) =&gt; (new Promise((resolve, reject) =&gt; {
31  const uploadParams = {
32    Bucket: S3_BUCKET_NAME,
33    Key: 'some-key',
34    Body: stream,
35  };
36  s3.upload(uploadParams, (err) =&gt; {
37    if (err) reject(err);
38    resolve(true);
39  });
40}));
41

This piece of code (based on the aws-sdk package) works fine. My issue here is that i want it to run with the @aws-sdk/client-s3 package in order to reduce the size of the project.

What doesn't work:

I first tried to use S3Client.send(PutObjectCommand):

1curl -X PUT -F &quot;data=@sample&quot; &quot;http://localhost:3000/upload/1/1&quot;
2const PassThrough = require('stream').PassThrough;
3
4async function uploadFile (req, res) {
5  try {
6    const firstS3Stream = new PassThrough();
7    const secondS3Stream = new PassThrough();
8    req.pipe(firstS3Stream);
9    req.pipe(secondS3Stream);
10
11    await Promise.all([
12      uploadToFirstS3(firstS3Stream),
13      uploadToSecondS3(secondS3Stream),
14    ]);
15    return res.end();
16  } catch (err) {
17    console.log(err)
18    return res.status(500).send({ error: 'Unexpected error during file upload' });
19  }
20}
21const aws = require('aws-sdk');
22
23const s3 = new aws.S3({
24  accessKeyId: S3_API_KEY,
25  secretAccessKey: S3_API_SECRET,
26  region: S3_REGION,
27  signatureVersion: 'v4',
28});
29
30const uploadToFirstS3 = (stream) =&gt; (new Promise((resolve, reject) =&gt; {
31  const uploadParams = {
32    Bucket: S3_BUCKET_NAME,
33    Key: 'some-key',
34    Body: stream,
35  };
36  s3.upload(uploadParams, (err) =&gt; {
37    if (err) reject(err);
38    resolve(true);
39  });
40}));
41const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
42
43const s3 = new S3Client({
44  credentials: {
45    accessKeyId: S3_API_KEY,
46    secretAccessKey: S3_API_SECRET,
47  },
48  region: S3_REGION,
49  signatureVersion: 'v4',
50});
51
52const uploadToFirstS3 = (stream) =&gt; (new Promise((resolve, reject) =&gt; {
53  const uploadParams = {
54    Bucket: S3_BUCKET_NAME,
55    Key:'some-key',
56    Body: stream,
57  };
58  s3.send(new PutObjectCommand(uploadParams), (err) =&gt; {
59    if (err) reject(err);
60    resolve(true);
61  });
62}));
63
1curl -X PUT -F &quot;data=@sample&quot; &quot;http://localhost:3000/upload/1/1&quot;
2const PassThrough = require('stream').PassThrough;
3
4async function uploadFile (req, res) {
5  try {
6    const firstS3Stream = new PassThrough();
7    const secondS3Stream = new PassThrough();
8    req.pipe(firstS3Stream);
9    req.pipe(secondS3Stream);
10
11    await Promise.all([
12      uploadToFirstS3(firstS3Stream),
13      uploadToSecondS3(secondS3Stream),
14    ]);
15    return res.end();
16  } catch (err) {
17    console.log(err)
18    return res.status(500).send({ error: 'Unexpected error during file upload' });
19  }
20}
21const aws = require('aws-sdk');
22
23const s3 = new aws.S3({
24  accessKeyId: S3_API_KEY,
25  secretAccessKey: S3_API_SECRET,
26  region: S3_REGION,
27  signatureVersion: 'v4',
28});
29
30const uploadToFirstS3 = (stream) =&gt; (new Promise((resolve, reject) =&gt; {
31  const uploadParams = {
32    Bucket: S3_BUCKET_NAME,
33    Key: 'some-key',
34    Body: stream,
35  };
36  s3.upload(uploadParams, (err) =&gt; {
37    if (err) reject(err);
38    resolve(true);
39  });
40}));
41const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
42
43const s3 = new S3Client({
44  credentials: {
45    accessKeyId: S3_API_KEY,
46    secretAccessKey: S3_API_SECRET,
47  },
48  region: S3_REGION,
49  signatureVersion: 'v4',
50});
51
52const uploadToFirstS3 = (stream) =&gt; (new Promise((resolve, reject) =&gt; {
53  const uploadParams = {
54    Bucket: S3_BUCKET_NAME,
55    Key:'some-key',
56    Body: stream,
57  };
58  s3.send(new PutObjectCommand(uploadParams), (err) =&gt; {
59    if (err) reject(err);
60    resolve(true);
61  });
62}));
63const { S3 } = require('@aws-sdk/client-s3');
64
65const s3 = new S3({
66  credentials: {
67    accessKeyId: S3_API_KEY,
68    secretAccessKey: S3_API_SECRET,
69  },
70  region: S3_REGION,
71  signatureVersion: 'v4',
72});
73
74const uploadToFirstS3 = (stream) =&gt; (new Promise((resolve, reject) =&gt; {
75  const uploadParams = {
76    Bucket: S3_BUCKET_NAME,
77    Key:'some-key',
78    Body: stream,
79  };
80  s3.putObject(uploadParams, (err) =&gt; {
81    if (err) reject(err);
82    resolve(true);
83  });
84}));
85

The two last examples both give me a 501 - Not Implemented error with the header Transfer-Encoding. I checked req.headers and there is no Transfer-Encoding in it, so I guess the sdk adds in the request to s3 ?

Since the first example (based on aws-sdk) works fine, I'm sure the error is not due to an empty body in the request as suggested in this SO thread.

Still, I thought maybe the stream wasn't readable yet when triggering the upload, thus I wrapped the calls to uploadToFirstS3 and uploadToSecondS3 with a callback triggered by the req.on('readable', callback) event, but nothing changed.

I would like to process the files in memory without storing it on the disk at any time. Is there a way to achieve it using the @aws-sdk/client-s3 package ?

ANSWER

Answered 2022-Feb-12 at 01:22

In S3 you can use the Upload class from @aws-sdk/lib-storage to do multipart uploads. Seems like there might be no mention of this in the docs site for @aws-sdk/client-s3 unfortunately.

It's mentioned in the upgrade guide here: https://github.com/aws/aws-sdk-js-v3/blob/main/UPGRADING.md#s3-multipart-upload

Here's the example provided in https://github.com/aws/aws-sdk-js-v3/tree/main/lib/lib-storage:

1curl -X PUT -F &quot;data=@sample&quot; &quot;http://localhost:3000/upload/1/1&quot;
2const PassThrough = require('stream').PassThrough;
3
4async function uploadFile (req, res) {
5  try {
6    const firstS3Stream = new PassThrough();
7    const secondS3Stream = new PassThrough();
8    req.pipe(firstS3Stream);
9    req.pipe(secondS3Stream);
10
11    await Promise.all([
12      uploadToFirstS3(firstS3Stream),
13      uploadToSecondS3(secondS3Stream),
14    ]);
15    return res.end();
16  } catch (err) {
17    console.log(err)
18    return res.status(500).send({ error: 'Unexpected error during file upload' });
19  }
20}
21const aws = require('aws-sdk');
22
23const s3 = new aws.S3({
24  accessKeyId: S3_API_KEY,
25  secretAccessKey: S3_API_SECRET,
26  region: S3_REGION,
27  signatureVersion: 'v4',
28});
29
30const uploadToFirstS3 = (stream) =&gt; (new Promise((resolve, reject) =&gt; {
31  const uploadParams = {
32    Bucket: S3_BUCKET_NAME,
33    Key: 'some-key',
34    Body: stream,
35  };
36  s3.upload(uploadParams, (err) =&gt; {
37    if (err) reject(err);
38    resolve(true);
39  });
40}));
41const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
42
43const s3 = new S3Client({
44  credentials: {
45    accessKeyId: S3_API_KEY,
46    secretAccessKey: S3_API_SECRET,
47  },
48  region: S3_REGION,
49  signatureVersion: 'v4',
50});
51
52const uploadToFirstS3 = (stream) =&gt; (new Promise((resolve, reject) =&gt; {
53  const uploadParams = {
54    Bucket: S3_BUCKET_NAME,
55    Key:'some-key',
56    Body: stream,
57  };
58  s3.send(new PutObjectCommand(uploadParams), (err) =&gt; {
59    if (err) reject(err);
60    resolve(true);
61  });
62}));
63const { S3 } = require('@aws-sdk/client-s3');
64
65const s3 = new S3({
66  credentials: {
67    accessKeyId: S3_API_KEY,
68    secretAccessKey: S3_API_SECRET,
69  },
70  region: S3_REGION,
71  signatureVersion: 'v4',
72});
73
74const uploadToFirstS3 = (stream) =&gt; (new Promise((resolve, reject) =&gt; {
75  const uploadParams = {
76    Bucket: S3_BUCKET_NAME,
77    Key:'some-key',
78    Body: stream,
79  };
80  s3.putObject(uploadParams, (err) =&gt; {
81    if (err) reject(err);
82    resolve(true);
83  });
84}));
85  import { Upload } from &quot;@aws-sdk/lib-storage&quot;;
86  import { S3Client } from &quot;@aws-sdk/client-s3&quot;;
87
88  const target = { Bucket, Key, Body };
89  try {
90    const parallelUploads3 = new Upload({
91      client: new S3Client({}),
92      tags: [...], // optional tags
93      queueSize: 4, // optional concurrency configuration
94      leavePartsOnError: false, // optional manually handle dropped parts
95      params: target,
96    });
97
98    parallelUploads3.on(&quot;httpUploadProgress&quot;, (progress) =&gt; {
99      console.log(progress);
100    });
101
102    await parallelUploads3.done();
103  } catch (e) {
104    console.log(e);
105  }
106

Source https://stackoverflow.com/questions/69884898

QUESTION

Spring Boot 2.5.x: Required request part 'file' is not present

Asked 2022-Jan-17 at 08:14

I have a file uploading api which was working perfectly fine under the spring boot version 2.1.13. After upgrading the version to 2.5.2, it started to throw an exception. Looking at the changelogs, I couldn't see anything significant changes that's related to Multipart processing. What could I be missing here? Below are the sample codes I have.

Exception

1org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2    at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:161) ~[spring-webmvc-5.3.8.jar:5.3.8]
3    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.8.jar:5.3.8]
4    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170) ~[spring-web-5.3.8.jar:5.3.8]
5    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-5.3.8.jar:5.3.8]
6    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
7    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
8    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
9    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
10    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
11    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
12    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.8.jar:5.3.8]
13    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.3.8.jar:5.3.8]
14    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) [tomcat-embed-core-9.0.48.jar:4.0.FR]
15

application.properties

1org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2    at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:161) ~[spring-webmvc-5.3.8.jar:5.3.8]
3    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.8.jar:5.3.8]
4    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170) ~[spring-web-5.3.8.jar:5.3.8]
5    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-5.3.8.jar:5.3.8]
6    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
7    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
8    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
9    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
10    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
11    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
12    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.8.jar:5.3.8]
13    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.3.8.jar:5.3.8]
14    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) [tomcat-embed-core-9.0.48.jar:4.0.FR]
15spring.servlet.multipart.enabled=true
16spring.servlet.multipart.max-file-size=20MB
17spring.servlet.multipart.max-request-size=20MB
18

controller end point

1org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2    at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:161) ~[spring-webmvc-5.3.8.jar:5.3.8]
3    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.8.jar:5.3.8]
4    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170) ~[spring-web-5.3.8.jar:5.3.8]
5    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-5.3.8.jar:5.3.8]
6    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
7    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
8    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
9    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
10    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
11    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
12    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.8.jar:5.3.8]
13    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.3.8.jar:5.3.8]
14    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) [tomcat-embed-core-9.0.48.jar:4.0.FR]
15spring.servlet.multipart.enabled=true
16spring.servlet.multipart.max-file-size=20MB
17spring.servlet.multipart.max-request-size=20MB
18@PostMapping(
19    value = &quot;/upload&quot;, 
20    consumes = MediaType.MULTIPART_FORM_DATA_VALUE, 
21    produces = MediaType.APPLICATION_JSON_VALUE
22)
23public ResponseEntity&lt;Object&gt; uploadFile(@RequestPart(&quot;file&quot;) MultipartFile file) {
24...
25}
26

Request Payload Sample

1org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2    at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:161) ~[spring-webmvc-5.3.8.jar:5.3.8]
3    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.8.jar:5.3.8]
4    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170) ~[spring-web-5.3.8.jar:5.3.8]
5    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-5.3.8.jar:5.3.8]
6    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
7    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
8    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
9    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
10    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
11    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
12    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.8.jar:5.3.8]
13    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.3.8.jar:5.3.8]
14    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) [tomcat-embed-core-9.0.48.jar:4.0.FR]
15spring.servlet.multipart.enabled=true
16spring.servlet.multipart.max-file-size=20MB
17spring.servlet.multipart.max-request-size=20MB
18@PostMapping(
19    value = &quot;/upload&quot;, 
20    consumes = MediaType.MULTIPART_FORM_DATA_VALUE, 
21    produces = MediaType.APPLICATION_JSON_VALUE
22)
23public ResponseEntity&lt;Object&gt; uploadFile(@RequestPart(&quot;file&quot;) MultipartFile file) {
24...
25}
26POST http://localhost:8080/upload
27Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGG9dgUb5THDV0eDB
28
29------WebKitFormBoundaryGG9dgUb5THDV0eDB
30Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;Sample.pdf&quot;
31Content-Type: application/pdf
32
33------WebKitFormBoundaryGG9dgUb5THDV0eDB--
34

Note: I don't have any MultipartResolver bean defined in my configuration. I tried adding the MultipartResolver bean definition as follows (only one at a time) but didn't seem to resolve the issue.

1org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2    at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:161) ~[spring-webmvc-5.3.8.jar:5.3.8]
3    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.8.jar:5.3.8]
4    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170) ~[spring-web-5.3.8.jar:5.3.8]
5    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-5.3.8.jar:5.3.8]
6    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
7    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
8    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
9    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
10    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
11    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
12    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.8.jar:5.3.8]
13    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.3.8.jar:5.3.8]
14    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) [tomcat-embed-core-9.0.48.jar:4.0.FR]
15spring.servlet.multipart.enabled=true
16spring.servlet.multipart.max-file-size=20MB
17spring.servlet.multipart.max-request-size=20MB
18@PostMapping(
19    value = &quot;/upload&quot;, 
20    consumes = MediaType.MULTIPART_FORM_DATA_VALUE, 
21    produces = MediaType.APPLICATION_JSON_VALUE
22)
23public ResponseEntity&lt;Object&gt; uploadFile(@RequestPart(&quot;file&quot;) MultipartFile file) {
24...
25}
26POST http://localhost:8080/upload
27Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGG9dgUb5THDV0eDB
28
29------WebKitFormBoundaryGG9dgUb5THDV0eDB
30Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;Sample.pdf&quot;
31Content-Type: application/pdf
32
33------WebKitFormBoundaryGG9dgUb5THDV0eDB--
34@Bean
35public CommonsMultipartResolver multipartResolver() { // didn't work
36    return new CommonsMultipartResolver();
37}
38
39@Bean
40public StandardServletMultipartResolver multipartResolver() { // didn't work
41    return new StandardServletMultipartResolver();
42}
43

ANSWER

Answered 2021-Aug-17 at 17:03

It turns out this issue was affected after the Spring Boot 2.2. Since that version, the filter HttpHiddenMethodFilter was disabled by default. The issue got fixed after enabling the filter in application.properties.

1org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2    at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:161) ~[spring-webmvc-5.3.8.jar:5.3.8]
3    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.8.jar:5.3.8]
4    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170) ~[spring-web-5.3.8.jar:5.3.8]
5    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-5.3.8.jar:5.3.8]
6    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
7    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
8    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
9    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
10    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
11    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
12    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.8.jar:5.3.8]
13    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.3.8.jar:5.3.8]
14    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) [tomcat-embed-core-9.0.48.jar:4.0.FR]
15spring.servlet.multipart.enabled=true
16spring.servlet.multipart.max-file-size=20MB
17spring.servlet.multipart.max-request-size=20MB
18@PostMapping(
19    value = &quot;/upload&quot;, 
20    consumes = MediaType.MULTIPART_FORM_DATA_VALUE, 
21    produces = MediaType.APPLICATION_JSON_VALUE
22)
23public ResponseEntity&lt;Object&gt; uploadFile(@RequestPart(&quot;file&quot;) MultipartFile file) {
24...
25}
26POST http://localhost:8080/upload
27Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGG9dgUb5THDV0eDB
28
29------WebKitFormBoundaryGG9dgUb5THDV0eDB
30Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;Sample.pdf&quot;
31Content-Type: application/pdf
32
33------WebKitFormBoundaryGG9dgUb5THDV0eDB--
34@Bean
35public CommonsMultipartResolver multipartResolver() { // didn't work
36    return new CommonsMultipartResolver();
37}
38
39@Bean
40public StandardServletMultipartResolver multipartResolver() { // didn't work
41    return new StandardServletMultipartResolver();
42}
43spring.mvc.hiddenmethod.filter.enabled=true
44

My Findings in Detail

The purpose of the above filter has nothing to do with the error I was getting. But the request parts was getting initialized as a side effect of executing the filter. More specifically, when the filter tries to retrieve the _method parameter value (e.g. request.getParameter("_method"), the getParameter method of the request instance internally seems to parse the parameters which then initializes the request parts. So when the filter was disabled in spring-boot version 2.2, there was nothing to initialize the request parts.

I feel like the request parts initialization should be fixed within the Spring framework itself. But until then, either we could enable the HttpHiddenMethodFilter filter, or we could define a custom filter that takes care of initializing the request parts, something like below:

1org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2    at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:161) ~[spring-webmvc-5.3.8.jar:5.3.8]
3    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.3.8.jar:5.3.8]
4    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170) ~[spring-web-5.3.8.jar:5.3.8]
5    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-5.3.8.jar:5.3.8]
6    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
7    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
8    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
9    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
10    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
11    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
12    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.8.jar:5.3.8]
13    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.3.8.jar:5.3.8]
14    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) [tomcat-embed-core-9.0.48.jar:4.0.FR]
15spring.servlet.multipart.enabled=true
16spring.servlet.multipart.max-file-size=20MB
17spring.servlet.multipart.max-request-size=20MB
18@PostMapping(
19    value = &quot;/upload&quot;, 
20    consumes = MediaType.MULTIPART_FORM_DATA_VALUE, 
21    produces = MediaType.APPLICATION_JSON_VALUE
22)
23public ResponseEntity&lt;Object&gt; uploadFile(@RequestPart(&quot;file&quot;) MultipartFile file) {
24...
25}
26POST http://localhost:8080/upload
27Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryGG9dgUb5THDV0eDB
28
29------WebKitFormBoundaryGG9dgUb5THDV0eDB
30Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;Sample.pdf&quot;
31Content-Type: application/pdf
32
33------WebKitFormBoundaryGG9dgUb5THDV0eDB--
34@Bean
35public CommonsMultipartResolver multipartResolver() { // didn't work
36    return new CommonsMultipartResolver();
37}
38
39@Bean
40public StandardServletMultipartResolver multipartResolver() { // didn't work
41    return new StandardServletMultipartResolver();
42}
43spring.mvc.hiddenmethod.filter.enabled=true
44@Configuration
45@Order(Ordered.HIGHEST_PRECEDENCE)
46public class RequestInitializerFilter extends OncePerRequestFilter {
47
48    @Override
49    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
50
51        request.getParameterNames(); // this takes care of initializing request `parts`
52
53        filterChain.doFilter(request, response);
54    }
55}
56

Source https://stackoverflow.com/questions/68765889

QUESTION

How to get a upload button in swagger for IFormFile combined with other properties?

Asked 2022-Jan-12 at 02:53

I have created a Asp.net core 3.1 web api with Swagger to upload files to server. the following code is working fine:

1    [HttpPost(&quot;PostFile&quot;)]
2    public ActionResult PostFile(IFormFile uploadedFile)
3    {            
4        var saveFilePath = Path.Combine(&quot;c:\\savefilepath\\&quot;, uploadedFile.FileName);
5        using (var stream = new FileStream(saveFilePath, FileMode.Create))
6        {
7            uploadedFile.CopyToAsync(stream);
8        }
9        return Ok();
10    }
11

I get a nice upload button in swagger when I try to run this.

enter image description here

However, now I wanted to use a different model. that has some more properties along with the IFormFile.

1    [HttpPost(&quot;PostFile&quot;)]
2    public ActionResult PostFile(IFormFile uploadedFile)
3    {            
4        var saveFilePath = Path.Combine(&quot;c:\\savefilepath\\&quot;, uploadedFile.FileName);
5        using (var stream = new FileStream(saveFilePath, FileMode.Create))
6        {
7            uploadedFile.CopyToAsync(stream);
8        }
9        return Ok();
10    }
11public class FileUploadRequest
12{
13    public string UploaderName { get; set; }
14    public string UploaderAddress { get; set; }
15    public IFormFile File { get; set; }
16}
17

When I try to use this model, I dont see any upload button in Swagger that will help me to attach the file in the request.

enter image description here

For some reason, it shows the IFormFile as String. How can I get a upload button here?

ANSWER

Answered 2022-Jan-12 at 02:53

In ASP.NET Core Web API, it binds application/json format data by default. But what your model need is multipart/form-data type data. So you need [FromForm] attribute to specific the source.

I use Swashbuckle.AspNetCore version 5.6.3 in ASP.NET Core 3.1:

1    [HttpPost(&quot;PostFile&quot;)]
2    public ActionResult PostFile(IFormFile uploadedFile)
3    {            
4        var saveFilePath = Path.Combine(&quot;c:\\savefilepath\\&quot;, uploadedFile.FileName);
5        using (var stream = new FileStream(saveFilePath, FileMode.Create))
6        {
7            uploadedFile.CopyToAsync(stream);
8        }
9        return Ok();
10    }
11public class FileUploadRequest
12{
13    public string UploaderName { get; set; }
14    public string UploaderAddress { get; set; }
15    public IFormFile File { get; set; }
16}
17[HttpPost]
18public ActionResult PostFile([FromForm]FileUploadRequest model)
19{
20
21}
22

Result:

enter image description here

Source https://stackoverflow.com/questions/70668520

QUESTION

Problem dealing with a space when moving JSON to Python

Asked 2022-Jan-04 at 23:11

I am high school math teacher who is teaching myself programming. My apologies in advance if I don't phrase some of this correctly.

I am collecting CSV data from the user and trying to move it to a SQLite database via Python.

Everything works fine unless one of the values has a space in it.

For example, here is part of my JavaScript object:

1Firstname: &quot;Bruce&quot;
2Grade: &quot;&quot;
3Lastname: &quot;Wayne Jr&quot;
4Nickname: &quot;&quot;
5

Here is the corresponding piece after applying JSON.stringify:

{"Firstname":"Bruce","Lastname":"Wayne Jr","Nickname":"","Grade":""}

This is then passed to Python via a form. In Python, I use:

1Firstname: &quot;Bruce&quot;
2Grade: &quot;&quot;
3Lastname: &quot;Wayne Jr&quot;
4Nickname: &quot;&quot;
5data = request.form.get(&quot;data&quot;)
6print(data)
7data2 = json.loads(data)
8print(data2)
9

I get a bunch of error messages, ending with: json.decoder.JSONDecodeError: Unterminated string starting at: line 1 column 250 (char 249) and the log of the first print gives:

1Firstname: &quot;Bruce&quot;
2Grade: &quot;&quot;
3Lastname: &quot;Wayne Jr&quot;
4Nickname: &quot;&quot;
5data = request.form.get(&quot;data&quot;)
6print(data)
7data2 = json.loads(data)
8print(data2)
9[{&quot;Firstname&quot;:&quot;Jason&quot;,&quot;Lastname&quot;:&quot;Bourne&quot;,&quot;Nickname&quot;:&quot;&quot;,&quot;Grade&quot;:&quot;10&quot;},
10 {&quot;Firstname&quot;:&quot;Steve&quot;,&quot;Lastname&quot;:&quot;McGarret&quot;,&quot;Nickname&quot;:&quot;5-0&quot;,&quot;Grade&quot;:&quot;&quot;},
11 {&quot;Firstname&quot;:&quot;Danny&quot;,&quot;Lastname&quot;:&quot;Williams&quot;,&quot;Nickname&quot;:&quot;Dano&quot;,&quot;Grade&quot;:&quot;12&quot;},
12 {&quot;Firstname&quot;:&quot;Bruce&quot;,&quot;Lastname&quot;:&quot;Wayne
13

So it seems to break on the space in "Wayne Jr".

I used what I learned here to build the basics:
https://bl.ocks.org/HarryStevens/0ce529b9b5e4ea17f8db25324423818f

I believe this JavaScript function is parsing the user data:

1Firstname: &quot;Bruce&quot;
2Grade: &quot;&quot;
3Lastname: &quot;Wayne Jr&quot;
4Nickname: &quot;&quot;
5data = request.form.get(&quot;data&quot;)
6print(data)
7data2 = json.loads(data)
8print(data2)
9[{&quot;Firstname&quot;:&quot;Jason&quot;,&quot;Lastname&quot;:&quot;Bourne&quot;,&quot;Nickname&quot;:&quot;&quot;,&quot;Grade&quot;:&quot;10&quot;},
10 {&quot;Firstname&quot;:&quot;Steve&quot;,&quot;Lastname&quot;:&quot;McGarret&quot;,&quot;Nickname&quot;:&quot;5-0&quot;,&quot;Grade&quot;:&quot;&quot;},
11 {&quot;Firstname&quot;:&quot;Danny&quot;,&quot;Lastname&quot;:&quot;Williams&quot;,&quot;Nickname&quot;:&quot;Dano&quot;,&quot;Grade&quot;:&quot;12&quot;},
12 {&quot;Firstname&quot;:&quot;Bruce&quot;,&quot;Lastname&quot;:&quot;Wayne
13function changeDataFromField(cb){
14   var arr = [];
15   $('#enter-data-field').val().replace( /\n/g, &quot;^^^xyz&quot; ).split( &quot;^^^xyz&quot; ).forEach(function(d){
16     arr.push(d.replace( /\t/g, &quot;^^^xyz&quot; ).split( &quot;^^^xyz&quot; ))
17   });
18   cb(csvToJson(arr));
19 }
20

Updates based on comments:
I am using a POST request. No AJAX.

There are actually 2 inputs for the user. A text box where they can paste CSV data and a file upload option. Here is some more of the JavaScript.

1Firstname: &quot;Bruce&quot;
2Grade: &quot;&quot;
3Lastname: &quot;Wayne Jr&quot;
4Nickname: &quot;&quot;
5data = request.form.get(&quot;data&quot;)
6print(data)
7data2 = json.loads(data)
8print(data2)
9[{&quot;Firstname&quot;:&quot;Jason&quot;,&quot;Lastname&quot;:&quot;Bourne&quot;,&quot;Nickname&quot;:&quot;&quot;,&quot;Grade&quot;:&quot;10&quot;},
10 {&quot;Firstname&quot;:&quot;Steve&quot;,&quot;Lastname&quot;:&quot;McGarret&quot;,&quot;Nickname&quot;:&quot;5-0&quot;,&quot;Grade&quot;:&quot;&quot;},
11 {&quot;Firstname&quot;:&quot;Danny&quot;,&quot;Lastname&quot;:&quot;Williams&quot;,&quot;Nickname&quot;:&quot;Dano&quot;,&quot;Grade&quot;:&quot;12&quot;},
12 {&quot;Firstname&quot;:&quot;Bruce&quot;,&quot;Lastname&quot;:&quot;Wayne
13function changeDataFromField(cb){
14   var arr = [];
15   $('#enter-data-field').val().replace( /\n/g, &quot;^^^xyz&quot; ).split( &quot;^^^xyz&quot; ).forEach(function(d){
16     arr.push(d.replace( /\t/g, &quot;^^^xyz&quot; ).split( &quot;^^^xyz&quot; ))
17   });
18   cb(csvToJson(arr));
19 }
20// Use the HTML5 File API to read the CSV
21  function changeDataFromUpload(evt, cb){
22    if (!browserSupportFileUpload()) {
23      console.error(&quot;The File APIs are not fully supported in this browser!&quot;);
24    } else {
25      var data = null;
26      var file = evt.target.files[0];
27      var fileName = file.name;
28      $(&quot;#filename&quot;).html(fileName);
29
30      if (file !== &quot;&quot;) {
31        var reader = new FileReader();
32
33        reader.onload = function(event) {
34          var csvData = event.target.result;
35          var parsed = Papa.parse(csvData);
36          cb(csvToJson(parsed.data));
37        };
38        reader.onerror = function() {
39          console.error(&quot;Unable to read &quot; + file.fileName);
40        };
41      }
42
43      reader.readAsText(file);
44      $(&quot;#update-data-from-file&quot;)[0].value = &quot;&quot;;
45    }
46  }
47
48  // Method that checks that the browser supports the HTML5 File API
49  function browserSupportFileUpload() {
50    var isCompatible = false;
51    if (window.File &amp;&amp; window.FileReader &amp;&amp; window.FileList &amp;&amp; window.Blob) {
52      isCompatible = true;
53    }
54    return isCompatible;
55  }
56
57  // Parse the CSV input into JSON
58  function csvToJson(data) {
59    var cols = [&quot;Firstname&quot;,&quot;Lastname&quot;,&quot;Nickname&quot;,&quot;Grade&quot;];
60    var out = [];
61    for (var i = 0; i &lt; data.length; i++){
62      var obj = {};
63      var row = data[i];
64      cols.forEach(function(col, index){
65        if (row[index]) {
66          obj[col] = row[index];
67        }
68        else {
69          obj[col] = &quot;&quot;;
70        }
71      });
72      out.push(obj);
73    }
74    return out;
75  }
76
77  //  Produces table for user to check appearance of data and button to complete upload
78  function makeTable(data) {
79    console.log(data);
80    send_data = JSON.stringify(data);
81    console.log(send_data);
82      var table_data = '&lt;table style=&quot;table-layout: fixed; width: 100%&quot; class=&quot;table table-striped&quot;&gt;';
83      table_data += '&lt;th&gt;First name&lt;/th&gt;&lt;th&gt;Last name&lt;/th&gt;&lt;th&gt;Nickname&lt;/th&gt;&lt;th&gt;Grade&lt;/th&gt;'
84      for(var count = 0; count &lt; data.length; count++) {
85        table_data += '&lt;tr&gt;';
86            table_data += '&lt;td&gt;'+data[count]['Firstname']+'&lt;/td&gt;';
87            table_data += '&lt;td&gt;'+data[count]['Lastname']+'&lt;/td&gt;';
88            table_data += '&lt;td&gt;'+data[count]['Nickname']+'&lt;/td&gt;';
89            table_data += '&lt;td&gt;'+data[count]['Grade']+'&lt;/td&gt;';
90        table_data += '&lt;/tr&gt;';
91        }
92      table_data += '&lt;/table&gt;';
93      table_data += '&lt;p&gt;&lt;form action=&quot;/uploaded&quot; method=&quot;post&quot;&gt;';
94      table_data += 'Does the data look OK? If so, click to upload.  ';
95      table_data += '&lt;button class=&quot;btn btn-primary&quot; type=&quot;submit&quot;&gt;Upload&lt;/button&gt;&lt;p&gt;';
96      table_data += '&lt;input type=&quot;hidden&quot; id=&quot;data&quot; name=&quot;data&quot; value='+send_data+'&gt;';
97      table_data += '&lt;input type=&quot;hidden&quot; name=&quot;class_id&quot; value=&quot;{{ class_id }}&quot;&gt;';
98      table_data += '&lt;/form&gt;';
99      table_data += 'Otherwise, fix the file and reload.';
100      document.getElementById(&quot;result_table&quot;).innerHTML = table_data;
101  }
102  &lt;/script&gt;
103

ANSWER

Answered 2022-Jan-03 at 04:51

The JavaScript can be made a lot simpler. If you do the following instead, do you have any problems with the JSON getting cut off?

1Firstname: &quot;Bruce&quot;
2Grade: &quot;&quot;
3Lastname: &quot;Wayne Jr&quot;
4Nickname: &quot;&quot;
5data = request.form.get(&quot;data&quot;)
6print(data)
7data2 = json.loads(data)
8print(data2)
9[{&quot;Firstname&quot;:&quot;Jason&quot;,&quot;Lastname&quot;:&quot;Bourne&quot;,&quot;Nickname&quot;:&quot;&quot;,&quot;Grade&quot;:&quot;10&quot;},
10 {&quot;Firstname&quot;:&quot;Steve&quot;,&quot;Lastname&quot;:&quot;McGarret&quot;,&quot;Nickname&quot;:&quot;5-0&quot;,&quot;Grade&quot;:&quot;&quot;},
11 {&quot;Firstname&quot;:&quot;Danny&quot;,&quot;Lastname&quot;:&quot;Williams&quot;,&quot;Nickname&quot;:&quot;Dano&quot;,&quot;Grade&quot;:&quot;12&quot;},
12 {&quot;Firstname&quot;:&quot;Bruce&quot;,&quot;Lastname&quot;:&quot;Wayne
13function changeDataFromField(cb){
14   var arr = [];
15   $('#enter-data-field').val().replace( /\n/g, &quot;^^^xyz&quot; ).split( &quot;^^^xyz&quot; ).forEach(function(d){
16     arr.push(d.replace( /\t/g, &quot;^^^xyz&quot; ).split( &quot;^^^xyz&quot; ))
17   });
18   cb(csvToJson(arr));
19 }
20// Use the HTML5 File API to read the CSV
21  function changeDataFromUpload(evt, cb){
22    if (!browserSupportFileUpload()) {
23      console.error(&quot;The File APIs are not fully supported in this browser!&quot;);
24    } else {
25      var data = null;
26      var file = evt.target.files[0];
27      var fileName = file.name;
28      $(&quot;#filename&quot;).html(fileName);
29
30      if (file !== &quot;&quot;) {
31        var reader = new FileReader();
32
33        reader.onload = function(event) {
34          var csvData = event.target.result;
35          var parsed = Papa.parse(csvData);
36          cb(csvToJson(parsed.data));
37        };
38        reader.onerror = function() {
39          console.error(&quot;Unable to read &quot; + file.fileName);
40        };
41      }
42
43      reader.readAsText(file);
44      $(&quot;#update-data-from-file&quot;)[0].value = &quot;&quot;;
45    }
46  }
47
48  // Method that checks that the browser supports the HTML5 File API
49  function browserSupportFileUpload() {
50    var isCompatible = false;
51    if (window.File &amp;&amp; window.FileReader &amp;&amp; window.FileList &amp;&amp; window.Blob) {
52      isCompatible = true;
53    }
54    return isCompatible;
55  }
56
57  // Parse the CSV input into JSON
58  function csvToJson(data) {
59    var cols = [&quot;Firstname&quot;,&quot;Lastname&quot;,&quot;Nickname&quot;,&quot;Grade&quot;];
60    var out = [];
61    for (var i = 0; i &lt; data.length; i++){
62      var obj = {};
63      var row = data[i];
64      cols.forEach(function(col, index){
65        if (row[index]) {
66          obj[col] = row[index];
67        }
68        else {
69          obj[col] = &quot;&quot;;
70        }
71      });
72      out.push(obj);
73    }
74    return out;
75  }
76
77  //  Produces table for user to check appearance of data and button to complete upload
78  function makeTable(data) {
79    console.log(data);
80    send_data = JSON.stringify(data);
81    console.log(send_data);
82      var table_data = '&lt;table style=&quot;table-layout: fixed; width: 100%&quot; class=&quot;table table-striped&quot;&gt;';
83      table_data += '&lt;th&gt;First name&lt;/th&gt;&lt;th&gt;Last name&lt;/th&gt;&lt;th&gt;Nickname&lt;/th&gt;&lt;th&gt;Grade&lt;/th&gt;'
84      for(var count = 0; count &lt; data.length; count++) {
85        table_data += '&lt;tr&gt;';
86            table_data += '&lt;td&gt;'+data[count]['Firstname']+'&lt;/td&gt;';
87            table_data += '&lt;td&gt;'+data[count]['Lastname']+'&lt;/td&gt;';
88            table_data += '&lt;td&gt;'+data[count]['Nickname']+'&lt;/td&gt;';
89            table_data += '&lt;td&gt;'+data[count]['Grade']+'&lt;/td&gt;';
90        table_data += '&lt;/tr&gt;';
91        }
92      table_data += '&lt;/table&gt;';
93      table_data += '&lt;p&gt;&lt;form action=&quot;/uploaded&quot; method=&quot;post&quot;&gt;';
94      table_data += 'Does the data look OK? If so, click to upload.  ';
95      table_data += '&lt;button class=&quot;btn btn-primary&quot; type=&quot;submit&quot;&gt;Upload&lt;/button&gt;&lt;p&gt;';
96      table_data += '&lt;input type=&quot;hidden&quot; id=&quot;data&quot; name=&quot;data&quot; value='+send_data+'&gt;';
97      table_data += '&lt;input type=&quot;hidden&quot; name=&quot;class_id&quot; value=&quot;{{ class_id }}&quot;&gt;';
98      table_data += '&lt;/form&gt;';
99      table_data += 'Otherwise, fix the file and reload.';
100      document.getElementById(&quot;result_table&quot;).innerHTML = table_data;
101  }
102  &lt;/script&gt;
103document.getElementById('update-data-from-file').addEventListener('change', function(evt){
104  var file = evt.target.files[0];
105  document.getElementById('filename').innerText = file.name
106
107  if (file === "")
108    return;
109
110  Papa.parse(file, {
111    header: true,
112    skipEmptyLines: true,
113    complete: function(results) {
114      json = results.data
115      console.log(json)
116      // Do stuff with the json here
117    }
118  });
119
120  document.getElementById('update-data-from-file').value = ''
121})
1Firstname: &quot;Bruce&quot;
2Grade: &quot;&quot;
3Lastname: &quot;Wayne Jr&quot;
4Nickname: &quot;&quot;
5data = request.form.get(&quot;data&quot;)
6print(data)
7data2 = json.loads(data)
8print(data2)
9[{&quot;Firstname&quot;:&quot;Jason&quot;,&quot;Lastname&quot;:&quot;Bourne&quot;,&quot;Nickname&quot;:&quot;&quot;,&quot;Grade&quot;:&quot;10&quot;},
10 {&quot;Firstname&quot;:&quot;Steve&quot;,&quot;Lastname&quot;:&quot;McGarret&quot;,&quot;Nickname&quot;:&quot;5-0&quot;,&quot;Grade&quot;:&quot;&quot;},
11 {&quot;Firstname&quot;:&quot;Danny&quot;,&quot;Lastname&quot;:&quot;Williams&quot;,&quot;Nickname&quot;:&quot;Dano&quot;,&quot;Grade&quot;:&quot;12&quot;},
12 {&quot;Firstname&quot;:&quot;Bruce&quot;,&quot;Lastname&quot;:&quot;Wayne
13function changeDataFromField(cb){
14   var arr = [];
15   $('#enter-data-field').val().replace( /\n/g, &quot;^^^xyz&quot; ).split( &quot;^^^xyz&quot; ).forEach(function(d){
16     arr.push(d.replace( /\t/g, &quot;^^^xyz&quot; ).split( &quot;^^^xyz&quot; ))
17   });
18   cb(csvToJson(arr));
19 }
20// Use the HTML5 File API to read the CSV
21  function changeDataFromUpload(evt, cb){
22    if (!browserSupportFileUpload()) {
23      console.error(&quot;The File APIs are not fully supported in this browser!&quot;);
24    } else {
25      var data = null;
26      var file = evt.target.files[0];
27      var fileName = file.name;
28      $(&quot;#filename&quot;).html(fileName);
29
30      if (file !== &quot;&quot;) {
31        var reader = new FileReader();
32
33        reader.onload = function(event) {
34          var csvData = event.target.result;
35          var parsed = Papa.parse(csvData);
36          cb(csvToJson(parsed.data));
37        };
38        reader.onerror = function() {
39          console.error(&quot;Unable to read &quot; + file.fileName);
40        };
41      }
42
43      reader.readAsText(file);
44      $(&quot;#update-data-from-file&quot;)[0].value = &quot;&quot;;
45    }
46  }
47
48  // Method that checks that the browser supports the HTML5 File API
49  function browserSupportFileUpload() {
50    var isCompatible = false;
51    if (window.File &amp;&amp; window.FileReader &amp;&amp; window.FileList &amp;&amp; window.Blob) {
52      isCompatible = true;
53    }
54    return isCompatible;
55  }
56
57  // Parse the CSV input into JSON
58  function csvToJson(data) {
59    var cols = [&quot;Firstname&quot;,&quot;Lastname&quot;,&quot;Nickname&quot;,&quot;Grade&quot;];
60    var out = [];
61    for (var i = 0; i &lt; data.length; i++){
62      var obj = {};
63      var row = data[i];
64      cols.forEach(function(col, index){
65        if (row[index]) {
66          obj[col] = row[index];
67        }
68        else {
69          obj[col] = &quot;&quot;;
70        }
71      });
72      out.push(obj);
73    }
74    return out;
75  }
76
77  //  Produces table for user to check appearance of data and button to complete upload
78  function makeTable(data) {
79    console.log(data);
80    send_data = JSON.stringify(data);
81    console.log(send_data);
82      var table_data = '&lt;table style=&quot;table-layout: fixed; width: 100%&quot; class=&quot;table table-striped&quot;&gt;';
83      table_data += '&lt;th&gt;First name&lt;/th&gt;&lt;th&gt;Last name&lt;/th&gt;&lt;th&gt;Nickname&lt;/th&gt;&lt;th&gt;Grade&lt;/th&gt;'
84      for(var count = 0; count &lt; data.length; count++) {
85        table_data += '&lt;tr&gt;';
86            table_data += '&lt;td&gt;'+data[count]['Firstname']+'&lt;/td&gt;';
87            table_data += '&lt;td&gt;'+data[count]['Lastname']+'&lt;/td&gt;';
88            table_data += '&lt;td&gt;'+data[count]['Nickname']+'&lt;/td&gt;';
89            table_data += '&lt;td&gt;'+data[count]['Grade']+'&lt;/td&gt;';
90        table_data += '&lt;/tr&gt;';
91        }
92      table_data += '&lt;/table&gt;';
93      table_data += '&lt;p&gt;&lt;form action=&quot;/uploaded&quot; method=&quot;post&quot;&gt;';
94      table_data += 'Does the data look OK? If so, click to upload.  ';
95      table_data += '&lt;button class=&quot;btn btn-primary&quot; type=&quot;submit&quot;&gt;Upload&lt;/button&gt;&lt;p&gt;';
96      table_data += '&lt;input type=&quot;hidden&quot; id=&quot;data&quot; name=&quot;data&quot; value='+send_data+'&gt;';
97      table_data += '&lt;input type=&quot;hidden&quot; name=&quot;class_id&quot; value=&quot;{{ class_id }}&quot;&gt;';
98      table_data += '&lt;/form&gt;';
99      table_data += 'Otherwise, fix the file and reload.';
100      document.getElementById(&quot;result_table&quot;).innerHTML = table_data;
101  }
102  &lt;/script&gt;
103document.getElementById('update-data-from-file').addEventListener('change', function(evt){
104  var file = evt.target.files[0];
105  document.getElementById('filename').innerText = file.name
106
107  if (file === "")
108    return;
109
110  Papa.parse(file, {
111    header: true,
112    skipEmptyLines: true,
113    complete: function(results) {
114      json = results.data
115      console.log(json)
116      // Do stuff with the json here
117    }
118  });
119
120  document.getElementById('update-data-from-file').value = ''
121})&lt;!DOCTYPE html&gt;
122&lt;html&gt;
123  &lt;head&gt;
124    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.0.2/papaparse.min.js"&gt;&lt;/script&gt;
125  &lt;/head&gt;
126  &lt;body&gt;
127
128    &lt;label&gt;
129      Upload CSV
130      &lt;input type="file" name="File Upload" id="update-data-from-file" accept=".csv" /&gt;
131    &lt;/label&gt;
132    &lt;div id="filename"&gt;No file chosen&lt;/div&gt;
133    
134  &lt;/body&gt;
135&lt;/html&gt;

Source https://stackoverflow.com/questions/70537825

QUESTION

Java can't upload file with @Pathvariable optional

Asked 2022-Jan-03 at 12:27

I try to build a todoapp with the function to upload files. Now i want to can upload files on a task or simply upload files without tasks. For that i need the @PathVariable Annotation to be optional.

This is my Controller:

1@PostMapping(&quot;/upload/{taskId}&quot;)
2private ResponseEntity&lt;String&gt; uploadFile(@CurrentUser UserPrincipal userPrincipal, @RequestParam(&quot;file&quot;) MultipartFile[] file, @PathVariable(required = false) String taskId) {
3    fileService.upload(userPrincipal.getUser(), file, taskId);
4    return new ResponseEntity&lt;&gt;(&quot;File uploaded&quot;, HttpStatus.OK);
5}
6

If i try it to upload with a TaskId it works. But when i try it to upload without a taskId it doesnt work. I got the error:

"405 Method not allowed"

Screenshot: enter image description here

Does somebody know how to fix this?

ANSWER

Answered 2022-Jan-03 at 10:59

If you want to use the @PathVariable as an optional be sure to bind both paths: @PostMapping(value = {"/upload/{taskId}", "/upload"}).

If you don't post the taskId spring will look for a controller that handles "/upload" instead of "/upload/{taskId}"

Personally i would use RequestParam instead of PathVariable for optional parameters

Source https://stackoverflow.com/questions/70564484

QUESTION

Antd File upload not getting reset

Asked 2021-Dec-20 at 09:58

I have a form. where file upload is mandatory. Validation works fine first time no file uploaded, but when i upload and delete file, Form doesn't throw validation error. Here is stakbiz https://stackblitz.com/edit/react-x27nfd

ANSWER

Answered 2021-Dec-20 at 09:58

You can use getValueFromEvent prop on Form.Item component like this:

1const normFile = (e) =&gt; {
2  if (Array.isArray(e)) {
3    return e;
4  }
5  return e &amp;&amp; e.fileList;
6};
7...
8&lt;Form.Item
9    label=&quot;File&quot;
10    name=&quot;file&quot;
11    getValueFromEvent={normFile}
12    rules={[
13      {
14        required: true,
15        message: 'Please input your File!',
16      },
17    ]}
18  &gt;
19   ... 
20&lt;/Form.Item&gt;
21

Here is edited version of your stackblitz link.

Source https://stackoverflow.com/questions/70419650

QUESTION

Load byte[] Property of Class Only When Needed

Asked 2021-Dec-16 at 19:52

I have a class that returns a List that is bound to a grid. One of my property is a byte[] array that should only be populated if someone double clicks on the cell in the grid cell with the file. At that point, the file should be downloaded an presented to the user. Just an event with a file name and Process.Start(...

Because I'm binding the list to the grid, it is calling the "File" property and filling the value giving it an eager type behavior rather than the lazy behavior I am looking for.

Is there any way I can stop this property from filling in the data class (below) without having to modify a UI level grid to explicitly not read the file column?

1public class Errors
2{
3//...
4    private bool hasFile;
5    public bool HasFile { get { return HasFile; } }
6    private byte[] file;
7    public byte[] File
8    {
9        get
10        {
11            if (HasFile) { file = FileHelper.DownloadAndDecompress(this.ID, &quot;ErrorsDownloadFile&quot;); }
12            return file;
13        }
14        set { file = value; }
15    }
16    
17    public static List&lt;Errors&gt; FindByAppName(string AppName, DateTime StartDate, DateTime EndDate) {/*...*/}
18//...
19}
20

I did some reading on Lazy<T> but, I'm struggling to get this to work into my regular workflow as when I implement it I can not assign to the setter the value to do file uploads...

Attempt but I can't assign a byte[] back to the File property as it is read only...

1public class Errors
2{
3//...
4    private bool hasFile;
5    public bool HasFile { get { return HasFile; } }
6    private byte[] file;
7    public byte[] File
8    {
9        get
10        {
11            if (HasFile) { file = FileHelper.DownloadAndDecompress(this.ID, &quot;ErrorsDownloadFile&quot;); }
12            return file;
13        }
14        set { file = value; }
15    }
16    
17    public static List&lt;Errors&gt; FindByAppName(string AppName, DateTime StartDate, DateTime EndDate) {/*...*/}
18//...
19}
20public bool HasFile { get { return HasFile; } }
21public Lazy&lt;byte[]&gt; File
22{
23    get
24    {
25        if (HasFile) { return new Lazy&lt;byte[]&gt;(() =&gt; FileHelper.DownloadAndDecompress(this.ID, &quot;ErrorsDownloadFile&quot;)); }
26        else { return null; };
27    }
28    set { }
29}
30

Any tips on how to properly implement a lazy property properly either using Lazy<T> or another method would be very much appreciated.

ANSWER

Answered 2021-Dec-16 at 19:50

If I understand you right, you want to implement lazy download, but eager upload

1public class Errors
2{
3//...
4    private bool hasFile;
5    public bool HasFile { get { return HasFile; } }
6    private byte[] file;
7    public byte[] File
8    {
9        get
10        {
11            if (HasFile) { file = FileHelper.DownloadAndDecompress(this.ID, &quot;ErrorsDownloadFile&quot;); }
12            return file;
13        }
14        set { file = value; }
15    }
16    
17    public static List&lt;Errors&gt; FindByAppName(string AppName, DateTime StartDate, DateTime EndDate) {/*...*/}
18//...
19}
20public bool HasFile { get { return HasFile; } }
21public Lazy&lt;byte[]&gt; File
22{
23    get
24    {
25        if (HasFile) { return new Lazy&lt;byte[]&gt;(() =&gt; FileHelper.DownloadAndDecompress(this.ID, &quot;ErrorsDownloadFile&quot;)); }
26        else { return null; };
27    }
28    set { }
29}
30// Eager download (will be used in lazy download)
31private byte[] DownLoad() {
32  // download here:
33  return FileHelper.DownloadAndDecompress(this.ID, &quot;ErrorsDownloadFile&quot;);
34}
35
36// Lazy download ...   
37private Lazy&lt;byte[]&gt; m_File;
38
39// ... which we assign in the constructor
40public MyClass() {
41  ...
42  m_File = new Lazy&lt;byte[]&gt;(Download); 
43  ...
44}
45
46// Our property
47public byte[] File {
48  get {
49    // Lazy download  
50    return m_File.Value;
51  }
52  set {
53    // we can't assign m_File.Value but we can recreate m_File
54    m_File = new Lazy&lt;byte[]&gt;(value);
55
56    //TODO: Upload here
57  }
58}
59

Source https://stackoverflow.com/questions/70384381

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in File Upload

Tutorials and Learning Resources are not available at this moment for File Upload

Share this Page

share link

Get latest updates on File Upload