0


我正在做dojo1.7。我想解析从 ajax 返回的多部分响应。
怎么做?有人可以建议我吗?
提前致谢!

4

1 回答 1

1

我不认为 Dojo 会原生地做到这一点。在客户端处理多部分是不寻常的。您需要为 multipart-mime 创建自己的 XHR 处理程序。

部分格式在Contact-Type标题中指定的边界处拆分内容:

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

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

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

在标准 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
            }
    });
});

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

注意:由于浏览器的安全性,您只能通过 XHR 加载数据,前提是数据与加载它的页面位于同一 url。(参见:Stackoverflow 对话)。

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

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属性。

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

于 2012-11-14T15:38:04.250 回答