Reputation: 39
I am working on dojo1.7. I want to parse multi-part response which i am getting from ajax return.
How to do it? Can somebody suggest me?
Thanks in advance!
Upvotes: 0
Views: 946
Reputation: 1381
I don't think Dojo will do this natively; it is unusal to handle multipart on the client. You will need to create your own XHR handler for multipart-mime.
The multipart format splits the content at the boundary specified in the Contact-Type heading:
eg.
Content-Type: multipart/form-data; boundary=AaB03x
You can use a simple string.split(<regx>) in javascript to split these parts. You'll then need to parse the individual parts. Each part will have it's own set of headers and the content will be encoded according to the format in the Content-Type.
If you are receiving attachments, it's likely that base64 encoding is being used; hence, you'll have to decode as well.
To you use you own handler in a stardard xhr call (once you have loaded it).
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
}
});
});
Here you have used a user-defined handler called "multipart", loaded from "mylib/multipart". Dojo will allow you to create any number of handlers and load them to parse data received in your scripts.
NB: Due to security in the browser you can only load data via XHR if it is on the same url as the page loading it. (see: Stackoverflow conversation).
I've created an example multipart handler below:
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);
}
});
});
This will parse the returned text from Xhr into an array of content objects. Each content object should contain a body attribute containing the raw-text body and a head attribute containing an object of its headers.
You will need to write extra code to handle the raw content if it isn't plain text. You might also want to throw a lot of test data at it, to ensure it works in all situations.
Upvotes: 1