Note that there are some explanatory texts on larger screens.

plurals
  1. POServer error posting MIME Multipart data directly with Javascript
    text
    copied!<p>I am trying to build Multipart Form Data directly in Javascript in order to send my data to a server. I know there are Ajax form plugins, but I really think they wont suit my needs as I will create binary data in the browser and send it as if it were a file submit (The server I will post to requires it that way).</p> <p>My problem now is that the simplest example of building text Multipart MIME data fails on the server side with an error: </p> <pre><code>500 Internal Server Error: Invalid boundary in multipart form </code></pre> <p>I have tried to reduce the code to a bare minimum: In this main.html (this is the name it will be refered to later in the server code) , there are both an html form to submit text the html-non-Ajax way and also a Javascript function which tries to replicate that with XmlHttprequest:</p> <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt; &lt;title&gt;Posting MIME Multipart directly in Javascript&lt;/title&gt; &lt;script&gt; function sendMimeMultipart(url, data) { boundary = '---------------------------1504702169761927311267328916' xhr = new XMLHttpRequest(); xhr.open("POST", url); //Build the MIME POST request. var body = "--" + boundary + "\r\n"; body += 'Content-Disposition: form-data; name="contents"\r\n\r\n'; body += data+"\r\n"; body += "--" + boundary + "--"+"\r\n"; var fileSize = body.length xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary); xhr.setRequestHeader("Content-Length", fileSize); xhr.send(body); return true; } function sendData() { sendMimeMultipart('http://localhost:8080/myhandler', "Hello World!"); } &lt;/script&gt; &lt;/head&gt; &lt;body onload='sendData()'&gt; &lt;form action = "myhandler" method = "post" enctype = "multipart/form-data"&gt; &lt;input type = "text" name = "contents"&gt; &lt;input type = "submit"&gt; &lt;/form&gt; &lt;/body&gt; &lt;/html&gt; </code></pre> <p>This is the Request object that arrives to the server when using the form:</p> <pre><code>Request: POST /myhandler Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3 Connection: keep-alive Content-Length: 187 Content-Type: multipart/form-data; boundary=---------------------------18171295601131570933197493099 Host: localhost:8080 Keep-Alive: 115 Referer: http://localhost:8080/ User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20 -----------------------------18171295601131570933197493099 Content-Disposition: form-data; name="contents" Hello World! -----------------------------18171295601131570933197493099-- </code></pre> <p>And this the Request object arriving to the server when using the Javascript function (sendMimeMultipart):</p> <pre><code>Request: POST /myhandler Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3 Cache-Control: no-cache Connection: keep-alive Content-Length: 185 Content-Type: multipart/form-data; charset=UTF-8, boundary=---------------------------1504702169761927311267328916 Host: localhost:8080 Keep-Alive: 115 Pragma: no-cache Referer: http://localhost:8080/ User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20 -----------------------------1504702169761927311267328916 Content-Disposition: form-data; name="contents" Hello World! -----------------------------1504702169761927311267328916-- </code></pre> <p>The difference of 2 bytes in Content-Length is because the browser generates the boundaries randomly, being sometimes longer and sometimes shorter. In this case it is one character longer, what accounts for the two byte difference in the two boundary occurrences.</p> <p>I dont think the server has much to do with this, bus just in case I post the server side code. It is an Appengine snippet intended only for localhost usage; the call to "localhost:8080/myhandler" retrieves the value of "contents" posted by the browser and stores it in a global variable. After that, a call to "localhost:8080/show" displays the text previously retrieved. As I mentioned before, if we send the data using the form, the text content is correctly saved and the "show" handler displays it. If however we use the Javascript, the line of code:</p> <pre><code> contents = self.request.get("contents") </code></pre> <p>In MyHandler (code below), produces the error.</p> <p>Here is the server code:</p> <pre><code>import cgi import datetime import logging import os from google.appengine.ext import db from google.appengine.api import users from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.api import images from google.appengine.ext.webapp import template from os import environ contents='' class mein(webapp.RequestHandler): def get(self): template_values = {} path = os.path.join(os.path.dirname(__file__), 'templates/main.html') self.response.out.write(template.render(path, template_values)) class MyHandler(webapp.RequestHandler): def post(self): global contents contents = self.request.get("contents") class Show(webapp.RequestHandler): def get(self): global contents self.response.headers['Content-Type'] = "text/plain" self.response.out.write(contents) application = webapp.WSGIApplication([ ('/', mein), ('/myhandler', MyHandler), ('/show', Show) ], debug=True) def main(): run_wsgi_app(application) if __name__ == '__main__': main() </code></pre> <p>Any idea of why this should be failing? I have tried a zillion different things, but I dont seem to be able to make it work or to understand the reason why it doesnt!.</p> <p>Thanks very much in advance for your ideas and help.<br> All the best:</p> <p>-Javier</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload