Recently I had to make a photo uploader on the server. Since the experience of using third-party scripts was already there, and there was often more time to develop the script from scratch, and it was decided to make the loader independently.
When accessing Google, it gives a lot of articles on downloading files via iframe. The algorithm generally boils down to:
1) Create a hidden frame (usually just width and height are zeroed through HTML and CSS properties)
2) Set the action form to the frame name.
3) Send the file. We are happy.
For ease of use, a separate “Start Download” button was not created, and the onChange handler for file input was hung.
')
Further testing: Chrome 9,10,11; Firefox 3.6 (the fourth was not yet released); Opera 9,10,11; IE 6 and IE 8, including compatibility with IE 7. Chrome, Opera, and FF have been tested on both Linux and Windows. The flight is normal, the test team passed. Sent to the live version of the site.
This is where the fun began. The site has several thousand visitors per day. And 6 of them wrote to tech support that the new method of uploading photos does not work. After adding error warnings to the script and logging them to the server, it turned out that the script actually does not work for several hundred people.
The first bug found was in IE 7. And it just touched the onChange event handler. As it turned out, this is a known bug - when you change the DOM tree in IE7, onChange is called. In it, the JS code changes the structure of the HTML document. This again causes onChange. Those. it turns out race condition and IE7 just ignores the changes and sends an empty file name. Solution: wrap the call in a function in setTimeout. This method works correctly in all tested browsers.
It remains to hack yourself on the nose: IE 7 and IE 8 in compatibility mode are completely different browsers ...
The next very interesting bug was in Opera 11, with only 3 users. Perhaps the opera itself is not to blame, but some auxiliary software. The fact is that the JSON response from the server has to be sent with the text / html mime type, not application / json. When trying to open application / json data in an iframe, some browsers suggested the user to download a binary file, while it should be quietly processed in JavaScript.
Opera sees that native HTML is being transmitted, why not to shove a banner there? And shoved. Naturally, the parser crashed while trying to digest such a string. Solution: firstly, it is desirable to use text / plain, secondly, cutting the string by the first occurrence of the opening and closing brace has been added.
The third glitch was the worst. Most often manifested in Firefox, IE and Chrome. The data was sent not to a hidden iframe, but to a new tab. The file, of course, was transferred to the server. However, JS could not turn to another tab, so the data was not displayed and it was impossible to use them.
Worst of all, it was not possible to repeat this bug - even IE worked out well on the machines of the team. A test page was made on which different ways to display / hide the frame were used. As expected, the visible frames all worked correctly, the hidden frames created tabs. It was solved simply - you need to frame the displayed frame in an invisible div (display: none).
I'll also tell you a little about the glitches that I managed to catch at the stage of writing the script.
Separately, I had to deal with distortions with cropper (a frame for selecting a specific image area). This script was just a third-party. With a static image, everything worked with a bang. But as soon as the image was created dynamically, various glitches were created - from the wrong size to full shading. Re-creating the object via delete / new did not help. By trial and error, it turned out that you need to initialize the script after the image is fully loaded. And for re-reading the parameters there is a reset method. Only in this way, and nothing else!
One of the most unpleasant problems was the fact that sending to the server of the intersecting forms (for example, a form in a form) does not always work correctly. And file input is a form element. The first solution that comes to mind is to copy data from input and create a similar DOM tree in another place. But not all browsers support this. Transferring the input over the DOM tree also failed. But if you frame it in DIV, then it can be moved quietly, along with the form element.
By the way, about the dynamic creation of elements. In the final version of the script, forms are created dynamically and placed in a layer that is not displayed at the beginning of the page. This avoided the intersection of forms and made it easier to create a large number of form loaders. But iframe could not be created dynamically, but then I finally saw with my own eyes a glitch with the opening of a new tab.
In conclusion, I would say that we did not regret about the decision to develop the script on our own. Personally, I got a lot of experience and funny moments when catching beetles, sometimes funny to hysterics and bloody tears. But the result is exactly what you need.