2

I am using a tool called TamperMonkey to modify a webpage for my personal convenience. TamperMonkey lets you modify the client-side HTML etc. by appending JavaScript to the page after it loads.

The webpage has a file chooser, but it doesn't let you drag-and-drop a file. I use this webpage a lot so having drag-and-drop functionality would really help.

This page has a form with a file input type. I've been reading, and there's no way to modify a file input type for security reasons. But, using TamperMonkey, I could change the input type of the file chooser to "hidden," then set the hidden input value to the file contents that I drop on the webpage, right? It's my understanding that the server couldn't tell the difference (if the name attribute is the same).

I don't know how to set the hidden input type to the same data the file chooser would have:

I've got my file here: const file = e.originalEvent.dataTransfer.files[0];

I've got my hidden input type by doing this: const hiddenField = $("iframe").contents().find(".file-input").attr('type','hidden')

I just don't know how to take file and set it on hiddenField. Should this value be base64 encoded? A blob? Regardless, what code would set the data correctly?

The form it's wrapped in looks like this:

<form ... method="post" enctype="multipart/form-data"> 

Important context for alternative suggestions: this file chooser input isn't on the page at all until you click a button. Then it shows up in an iframe.

I am using firefox.

6
  • Are you able to share more code? or even the url for the website? Commented Oct 1, 2020 at 17:44
  • @Goldwave I can't share the website. I can share code if you tell me what more you are looking for. Commented Oct 1, 2020 at 18:06
  • Have you tried dragging the file onto the select button? the "Select file to upload" button. Or is there no such thing? Commented Oct 1, 2020 at 18:11
  • @Goldwave it doesn't work. The select button is in a pop-up and I have to click something before it shows up. Commented Oct 1, 2020 at 18:15
  • Some ideas. 1) In dragover event on document.body change the style of the existing file input so it covers the entire page e.g. add a humongous transparent border and use absolute positioning + z-index 2) replace the submit event of the page and construct the payload yourself using FormData API which can directly use a file blob that you would read from the file's contents in your drop event handler. Commented Oct 1, 2020 at 18:39

1 Answer 1

1
+100

It is possible to modify a file input type with Tampermonkey.

If you are not able to add drag and drop support to the input itself straight away, you can implement drag and drop using another dom element and use them as below.

const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655 new DataTransfer(); // specs compliant (as of March 2018 only Chrome) dT.items.add(new File([dataURItoBlob(image)], '1.jpg', { type: 'image/jpeg' })); dT.items.add(new File([dataURItoBlob(image2)], '2.jpg', { type: 'image/jpeg' })); // then ... // $("iframe").contents().find(".file-input").get(0).files = dT.files; 

That snippet of code was tested working, in a similar setting where a file input was being attached to the page dynamically after clicking a button. The images were drag n dropped onto the page using a different div.

Sign up to request clarification or add additional context in comments.

2 Comments

I already have the file: const file = e.originalEvent.dataTransfer.files[0]; I'm going to attempt to use the last line of your answer.
Would be nice to link to where you pick half of your code...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.