如何在dojo中解析多部分响应

时间:2012-11-12 14:13:07

标签: ajax dojo response multipart


我正在研究dojo1.7。我想解析我从ajax返回的多部分响应。
如何做到这一点?有人可以建议我吗?
提前谢谢!

1 个答案:

答案 0 :(得分:1)

我不认为Dojo会原生这样做;在客户端处理multipart是不常见的。您需要为multipart-mime创建自己的XHR处理程序。

multipart format将内容拆分为联系人类型标题中指定的边界:

eg.
Content-Type: multipart/form-data; boundary=AaB03x

您可以在javascript中使用简单的 string.split(< regx>)来拆分这些部分。然后,您需要解析各个部分。每个部分都有自己的标题集,内容将根据Content-Type中的格式进行编码。

如果您正在接收附件,则可能正在使用base64编码;因此,你也必须解码。

在stardard xhr调用中使用自己的处理程序(一旦加载它)。

require(["dojo/_base/xhr", "mylib/multipart"], function(xhr){
    xhr.get({
            "url": "<URL TO MULIPART DATA>",
            "handleAs": "multipart",
            "preventCache": true,
            load: function(data){
                // Do something with the multipart data
            }
    });
});

在这里,您使用了一个名为&#34; multipart&#34;的用户定义处理程序,从&#34; mylib / multipart&#34;加载。 Dojo允许您创建任意数量的处理程序并加载它们来解析脚本中收到的数据。

NB:由于浏览器的安全性,您只能通过XHR加载数据,如果它与加载页面的网址相同。 (见:Stackoverflow conversation)。

我在下面创建了一个示例多部分处理程序:

require([
    "dojo/_base/xhr",
    "dojo/_base/array",
    "dojo/_base/lang"
], function(xhr, array, lang){
    lang.mixin(xhr.contentHandlers, {
        "multipart": function(response){
            var parser = {
                parse: function(response){
                    var parts = new Array();
                    var boundary = parser._getBoundary(response);
                    if(boundary){
                        parts =  parser._getParts(
                            response.responseText,
                            boundary
                        );
                    }
                    return parts;  // return empty array if parsing could not be done
                },

                _getBoundary: function(response){
                    var contentType = response.getResponseHeader("Content-Type");
                    if(/boundary\=/.test(contentType)){
                        var parse = /boundary\=(.*?)(;|$)/.exec(contentType);
                        return parse[1];
                    }
                    return false;  // Return false if no boundary found
                },

                _getParts: function(text, boundary){
                    var parsed = new Array();
                    var splitter =new RegExp(boundary+"[\r\n]+","g");
                    var parts = text.split(splitter);  // Split at the boundary

                    array.forEach(parts, function(part){
                        var headBody = part.split("\n\n");
                        if(headBody.length > 0){
                            var head = lang.trim(headBody[0]);
                            var body = headBody[1];
                            if(head != ""){  // Don't parse if no header, probably an error
                                parsed.push({
                                    "head": parser._parseHeaders(head),
                                    "body":body
                                });
                            }
                        }
                    }, this);

                    return parsed;
                },

                _parseHeaders: function(headerText){
                    // Headers should be in format: Header: Value
                    var header = {};
                    var lines = headerText.split(/[\r\n]/);
                    array.forEach(lines, function(line){
                        var parts = line.split(":");
                        if(parts.length > 0){
                            header[lang.trim(parts[0])] = lang.trim(parts[1]);
                        }
                    }, this);
                    return header;
                }
            };

            return parser.parse(response);
        }
    });
});

这会将返回的文本从Xhr解析为内容对象数组。每个内容对象都应包含一个 body 属性,其中包含原始文本正文和包含其标题对象的 head 属性。

如果原始内容不是纯文本,您将需要编写额外的代码来处理原始内容。您可能还想在其上投入大量测试数据,以确保它适用于所有情况。