1// Because we want to access DOM nodes,
2// we initialize our script at page load.
3window.addEventListener( 'load', function () {
4
5 // These variables are used to store the form data
6 const text = document.getElementById( "theText" );
7 const file = {
8 dom : document.getElementById( "theFile" ),
9 binary : null
10 };
11
12 // Use the FileReader API to access file content
13 const reader = new FileReader();
14
15 // Because FileReader is asynchronous, store its
16 // result when it finishes to read the file
17 reader.addEventListener( "load", function () {
18 file.binary = reader.result;
19 } );
20
21 // At page load, if a file is already selected, read it.
22 if( file.dom.files[0] ) {
23 reader.readAsBinaryString( file.dom.files[0] );
24 }
25
26 // If not, read the file once the user selects it.
27 file.dom.addEventListener( "change", function () {
28 if( reader.readyState === FileReader.LOADING ) {
29 reader.abort();
30 }
31
32 reader.readAsBinaryString( file.dom.files[0] );
33 } );
34
35 // sendData is our main function
36 function sendData() {
37 // If there is a selected file, wait it is read
38 // If there is not, delay the execution of the function
39 if( !file.binary && file.dom.files.length > 0 ) {
40 setTimeout( sendData, 10 );
41 return;
42 }
43
44 // To construct our multipart form data request,
45 // We need an XMLHttpRequest instance
46 const XHR = new XMLHttpRequest();
47
48 // We need a separator to define each part of the request
49 const boundary = "blob";
50
51 // Store our body request in a string.
52 let data = "";
53
54 // So, if the user has selected a file
55 if ( file.dom.files[0] ) {
56 // Start a new part in our body's request
57 data += "--" + boundary + "\r\n";
58
59 // Describe it as form data
60 data += 'content-disposition: form-data; '
61 // Define the name of the form data
62 + 'name="' + file.dom.name + '"; '
63 // Provide the real name of the file
64 + 'filename="' + file.dom.files[0].name + '"\r\n';
65 // And the MIME type of the file
66 data += 'Content-Type: ' + file.dom.files[0].type + '\r\n';
67
68 // There's a blank line between the metadata and the data
69 data += '\r\n';
70
71 // Append the binary data to our body's request
72 data += file.binary + '\r\n';
73 }
74
75 // Text data is simpler
76 // Start a new part in our body's request
77 data += "--" + boundary + "\r\n";
78
79 // Say it's form data, and name it
80 data += 'content-disposition: form-data; name="' + text.name + '"\r\n';
81 // There's a blank line between the metadata and the data
82 data += '\r\n';
83
84 // Append the text data to our body's request
85 data += text.value + "\r\n";
86
87 // Once we are done, "close" the body's request
88 data += "--" + boundary + "--";
89
90 // Define what happens on successful data submission
91 XHR.addEventListener( 'load', function( event ) {
92 alert( 'Yeah! Data sent and response loaded.' );
93 } );
94
95 // Define what happens in case of error
96 XHR.addEventListener( 'error', function( event ) {
97 alert( 'Oops! Something went wrong.' );
98 } );
99
100 // Set up our request
101 XHR.open( 'POST', 'https://example.com/cors.php' );
102
103 // Add the required HTTP header to handle a multipart form data POST request
104 XHR.setRequestHeader( 'Content-Type','multipart/form-data; boundary=' + boundary );
105
106 // And finally, send our data.
107 XHR.send( data );
108 }
109
110 // Access our form...
111 const form = document.getElementById( "theForm" );
112
113 // ...to take over the submit event
114 form.addEventListener( 'submit', function ( event ) {
115 event.preventDefault();
116 sendData();
117 } );
118} );