text: // This [jQuery](http://jquery.com/) plugin implements an `<iframe>`
  // [transport](http://api.jquery.com/extending-ajax/#Transports) so that
  // `$.ajax()` calls support the uploading of files using standard HTML file
  // input fields. This is done by switching the exchange from `XMLHttpRequest`
  // to a hidden `iframe` element containing a form that is submitted.
  
  // The [source for the plugin](http://github.com/cmlenz/jquery-iframe-transport)
  // is available on [Github](http://github.com/) and dual licensed under the MIT
  // or GPL Version 2 licenses.
  
  // ## Usage
  
  // To use this plugin, you simply add an `iframe` option with the value `true`
  // to the Ajax settings an `$.ajax()` call, and specify the file fields to
  // include in the submssion using the `files` option, which can be a selector,
  // jQuery object, or a list of DOM elements containing one or more
  // `<input type="file">` elements:
  
  //     $("#myform").submit(function() {
  //         $.ajax(this.action, {
  //             files: $(":file", this),
  //             iframe: true
  //         }).complete(function(data) {
  //             console.log(data);
  //         });
  //     });
  
  // The plugin will construct hidden `<iframe>` and `<form>` elements, add the
  // file field(s) to that form, submit the form, and process the response.
  
  // If you want to include other form fields in the form submission, include
  // them in the `data` option, and set the `processData` option to `false`:
  
  //     $("#myform").submit(function() {
  //         $.ajax(this.action, {
  //             data: $(":text", this).serializeArray(),
  //             files: $(":file", this),
  //             iframe: true,
  //             processData: false
  //         }).complete(function(data) {
  //             console.log(data);
  //         });
  //     });
  
  // ### Response Data Types
  
  // As the transport does not have access to the HTTP headers of the server
  // response, it is not as simple to make use of the automatic content type
  // detection provided by jQuery as with regular XHR. If you can't set the
  // expected response data type (for example because it may vary depending on
  // the outcome of processing by the server), you will need to employ a
  // workaround on the server side: Send back an HTML document containing just a
  // `<textarea>` element with a `data-type` attribute that specifies the MIME
  // type, and put the actual payload in the textarea:
  
  //     <textarea data-type="application/json">
  //       {"ok": true, "message": "Thanks so much"}
  //     </textarea>
  
  // The iframe transport plugin will detect this and pass the value of the
  // `data-type` attribute on to jQuery as if it was the "Content-Type" response
  // header, thereby enabling the same kind of conversions that jQuery applies
  // to regular responses. For the example above you should get a Javascript
  // object as the `data` parameter of the `complete` callback, with the
  // properties `ok: true` and `message: "Thanks so much"`.
  
  // ### Handling Server Errors
  
  // Another problem with using an `iframe` for file uploads is that it is
  // impossible for the javascript code to determine the HTTP status code of the
  // servers response. Effectively, all of the calls you make will look like they
  // are getting successful responses, and thus invoke the `done()` or
  // `complete()` callbacks. You can only determine communicate problems using
  // the content of the response payload. For example, consider using a JSON
  // response such as the following to indicate a problem with an uploaded file:
  
  //     <textarea data-type="application/json">
  //       {"ok": false, "message": "Please only upload reasonably sized files."}
  //     </textarea>
  
  // ### Compatibility
  
  // This plugin has primarily been tested on Safari 5 (or later), Firefox 4 (or
  // later), and Internet Explorer (all the way back to version 6). While I
  // haven't found any issues with it so far, I'm fairly sure it still doesn't
  // work around all the quirks in all different browsers. But the code is still
  // pretty simple overall, so you should be able to fix it and contribute a
  // patch :)
  
  // ## Annotated Source
  
  (function($, undefined) {
    "use strict";
  
    // Register a prefilter that checks whether the `iframe` option is set, and
    // switches to the "iframe" data type if it is `true`.
    $.ajaxPrefilter(function(options, origOptions, jqXHR) {
      if (options.iframe) {
        options.originalURL = options.url;
        return "iframe";
      }
    });
  
    // Register a transport for the "iframe" data type. It will only activate
    // when the "files" option has been set to a non-empty list of enabled file
    // inputs.
    $.ajaxTransport("iframe", function(options, origOptions, jqXHR) {
      var form = null,
          iframe = null,
          name = "iframe-" + $.now(),
          files = $(options.files).filter(":file:enabled"),
          markers = null,
          accepts = null;
  
      // This function gets called after a successful submission or an abortion
      // and should revert all changes made to the page to enable the
      // submission via this transport.
      function cleanUp() {
        markers.prop("disabled", false);
        form.remove();
        iframe.one("load", function() { iframe.remove(); });
        iframe.attr("src", "javascript:false;");
      }
  
      // Remove "iframe" from the data types list so that further processing is
      // based on the content type returned by the server, without attempting an
      // (unsupported) conversion from "iframe" to the actual type.
      options.dataTypes.shift();
  
      // Use the data from the original AJAX options, as it doesn't seem to be 
      // copied over since jQuery 1.7.
      // See https://github.com/cmlenz/jquery-iframe-transport/issues/6
  
      //反序列化
      options.data = base.tools.parseQueryString(origOptions.data);
  
      if (files.length) {
        form = $("<form enctype='multipart/form-data' method='post'></form>").
          hide().attr({action: options.originalURL, target: name});
  
        // If there is any additional data specified via the `data` option,
        // we add it as hidden fields to the form. This (currently) requires
        // the `processData` option to be set to false so that the data doesn't
        // get serialized to a string.
        if (typeof(options.data) === "string" && options.data.length > 0) {
          $.error("data must not be serialized");
        }
        $.each(options.data || {}, function(name, value) {
          if ($.isPlainObject(value)) {
            name = value.name;
            value = value.value;
          }
          $("<input type='hidden' />").attr({name:  name, value: value}).
            appendTo(form);
        });
  
        // Add a hidden `X-Requested-With` field with the value `IFrame` to the
        // field, to help server-side code to determine that the upload happened
        // through this transport.
        $("<input type='hidden' value='IFrame' name='X-Requested-With' />").
          appendTo(form);
  
        // Borrowed straight from the JQuery source.
        // Provides a way of specifying the accepted data type similar to the
        // HTTP "Accept" header
        if (options.dataTypes[0] && options.accepts[options.dataTypes[0]]) {
          accepts = options.accepts[options.dataTypes[0]] +
                    (options.dataTypes[0] !== "*" ? ", */*; q=0.01" : "");
        } else {
          accepts = options.accepts["*"];
        }
        $("<input type='hidden' name='X-HTTP-Accept'>").
          attr("value", accepts).appendTo(form);
  
  
  
        // Move the file fields into the hidden form, but first remember their
        // original locations in the document by replacing them with disabled
        // clones. This should also avoid introducing unwanted changes to the
        // page layout during submission.
        markers = files.after(function(idx) {
          return $(this).clone().prop("disabled", true);
        }).next();
  
        files.appendTo(form);
  
        //压入_token到表单
        $('input[name=_token]').clone(true).appendTo(form)
  
        return {
  
          // The `send` function is called by jQuery when the request should be
          // sent.
          send: function(headers, completeCallback) {
            iframe = $("<iframe src='javascript:false;' name='" + name +
              "' id='" + name + "' style='display:none'></iframe>");
  
            // The first load event gets fired after the iframe has been injected
            // into the DOM, and is used to prepare the actual submission.
            iframe.one("load", function() {
  
              // The second load event gets fired when the response to the form
              // submission is received. The implementation detects whether the
              // actual payload is embedded in a `<textarea>` element, and
              // prepares the required conversions to be made in that case.
              iframe.one("load", function() {
                var doc = this.contentWindow ? this.contentWindow.document :
                  (this.contentDocument ? this.contentDocument : this.document),
                  root = doc.documentElement ? doc.documentElement : doc.body,
                  textarea = root.getElementsByTagName("textarea")[0],
                  type = textarea && textarea.getAttribute("data-type") || null,
                  status = textarea && textarea.getAttribute("data-status") || 200,
                  statusText = textarea && textarea.getAttribute("data-statusText") || "OK",
                  content = {
                    html: root.innerHTML,
                    text: type ?
                      textarea.value :
                      root ? (root.textContent || root.innerText) : null
                  };
                cleanUp();
                completeCallback(status, statusText, content, type ?
                  ("Content-Type: " + type) :
                  null);
              });
  
              // Now that the load handler has been set up, submit the form.
              form[0].submit();
            });
  
            // After everything has been set up correctly, the form and iframe
            // get injected into the DOM so that the submission can be
            // initiated.
            $("body").append(form, iframe);
          },
  
          // The `abort` function is called by jQuery when the request should be
          // aborted.
          abort: function() {
            if (iframe !== null) {
              iframe.unbind("load").attr("src", "javascript:false;");
              cleanUp();
            }
          }
  
        };
      }
    });
  
  })(jQuery);
  