title: XMLHttpRequest: Multipart/Related POST with XML and image as payload
body: <p>I'm trying to POST an image (with Metadata) to Picasa Webalbums from within a Chrome-Extension. Note that a regular post with Content-Type image/xyz works, as I described <a href="https://stackoverflow.com/q/8243698/420615">here</a>. However, I wish to include a description/keywords and the <a href="http://code.google.com/intl/de-DE/apis/picasaweb/docs/2.0/developers_guide_protocol.html" rel="nofollow noreferrer">protocol specification</a> describes a <a href="http://code.google.com/intl/de-DE/apis/picasaweb/docs/2.0/developers_guide_protocol.html#PostPhotoWithMetadata" rel="nofollow noreferrer">multipart/related format</a> with a XML and data part.</p>
  
  <p>I'm getting the Data through HTML5 FileReader and user file input. I retrieve a binary 
  String using </p>
  
  <pre><code>FileReader.readAsBinaryString(file);
  </code></pre>
  
  <p>Assume this is my callback code once the FileReader has loaded the string:</p>
  
  <pre><code>function upload_to_album(binaryString, filetype, albumid) {
  
      var method = 'POST';
      var url = 'http://picasaweb.google.com/data/feed/api/user/default/albumid/' + albumid;
      var request = gen_multipart('Title', 'Description', binaryString, filetype);
      var xhr = new XMLHttpRequest();
      xhr.open(method, url, true);
      xhr.setRequestHeader("GData-Version", '3.0');
      xhr.setRequestHeader("Content-Type",  'multipart/related; boundary="END_OF_PART"');
      xhr.setRequestHeader("MIME-version", "1.0");
      // Add OAuth Token
      xhr.setRequestHeader("Authorization", oauth.getAuthorizationHeader(url, method, ''));
      xhr.onreadystatechange = function(data) {
          if (xhr.readyState == 4) {
              // .. handle response
          }
      };
      xhr.send(request);
  }   
  </code></pre>
  
  <p>The gen_multipart function just generates the multipart from the input values and the XML template and produces the exact same output <a href="http://code.google.com/intl/de-DE/apis/picasaweb/docs/2.0/developers_guide_protocol.html#PostPhotoWithMetadata" rel="nofollow noreferrer">as the specification</a> (apart from ..binary image data..), but for sake of completeness, here it is:</p>
  
  <pre><code>function gen_multipart(title, description, image, mimetype) {
      var multipart = ['Media multipart posting', "   \n", '--END_OF_PART', "\n",
      'Content-Type: application/atom+xml',"\n","\n",
      "&lt;entry xmlns='http://www.w3.org/2005/Atom'&gt;", '&lt;title&gt;', title, '&lt;/title&gt;',
      '&lt;summary&gt;', description, '&lt;/summary&gt;',
      '&lt;category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#photo" /&gt;',
      '&lt;/entry&gt;', "\n", '--END_OF_PART', "\n",
      'Content-Type:', mimetype, "\n\n",
      image, "\n", '--END_OF_PART--'];
      return multipart.join("");
  }
  </code></pre>
  
  <p>The problem is, that the POST payload differs from the raw image data, and thus leads to a Bad Request (Picasa won't accept the image), although it worked fine when using</p>
  
  <pre><code>xhr.send(file) // With content-type set to file.type
  </code></pre>
  
  <p>My question is, how do I get the <em>real</em> binary image to include it in the multipart? I assume it is mangled by just appending it to the xml string, but I can't seem to get it fixed.</p>
  
  <p>Note that due to an <a href="http://code.google.com/p/gdata-issues/issues/detail?id=151" rel="nofollow noreferrer">old bug in Picasa</a>, base64 is not the solution.</p>