将JavaScript数组转换为JSON对象
我正在修改Google Apps脚本中的邮件合并项目。我面临的问题是如何使电子邮件正文显示内嵌图像。目前,在调用GmailApp.sendEmail()之后,原始电子邮件模板中的所有内嵌图像将显示为附件。将JavaScript数组转换为JSON对象
我的猜测是,内嵌图像,如果我找到一些方式来imgVars数组转换成这样的JSON对象(从example in GAS documentation拍摄)显示:
MailApp.sendEmail(
"[email protected]",
"Logos",
"",
{ htmlBody:
"inline Google Logo<img src='cid:googleLogo'> images! <br/> inline YouTube Logo <img src='cid:youTubeLogo'>",
inlineImages:
{ googleLogo: googleLogoBlob,
youTubeLogo: youtTubeLogoBlob
}
}
);
所以我尝试做的是转换一个这样的数组:
var array = { item1, item2, item3 };
要JSON对象是这样的:
var json = { item1Name: item1,
item2Name: item2,
item3Name: item3
};
下面是从邮件合并的代码片段我工作:
//---------------------------------------------------------------
// If there are inline images in the body of the email
// Find them and store them in an array, imgVars
//---------------------------------------------------------------
if(emailTemplate.search(/<\img/ != -1)) {
var inlineImages = {};
// Extract all images from the email body
var imgVars = emailTemplate.match(/<img[^>]+>/g);
// For each image, extract its respective title attribute
for (i in imgVars) {
var title = imgVars[i].match(/title="([^\"]+\")/);
if (title != null) {
title = title[1].substr(0, title[1].length-1);
for (j in attachments) {
if (attachments[j].getName() == title) {
inlineImages[title] = attachments[j].copyBlob();
attachments.splice(j,1);
}
}
var newImg = imgVars[i].replace(/src="[^\"]+\"/,"src=\"cid:"+title+"\"");
emailTemplate = emailTemplate.replace(imgVars[i],newImg);
}
}
}
objects = getRowsData(dataSheet, dataRange);
for (var i = 0; i < objects.length; ++i) {
var rowData = objects[i];
if(rowData.emailSent != "EMAIL_SENT") {
// Replace markers (for instance ${"First Name"}) with the
// corresponding value in a row object (for instance rowData.firstName).
var emailText = fillInTemplateFromObject(emailTemplate, rowData);
var emailSubject = fillInTemplateFromObject(selectedTemplate.getSubject(), rowData);
GmailApp.sendEmail(rowData.emailAddress, emailSubject, emailText,
{name: e.parameter.name,
attachments: attachments,
htmlBody: emailText,
cc: cc,
bcc: bcc,
inlineImages: inlineImages});
一些评论:
> var array = { item1, item2, item3 };
即语法不正确,数组文本应该是:
var array = [ item1, item2, item3 ];
[...]
> if (emailTemplate.search(/<\img/ != -1)) {
反斜杠之前img
是不必要的,模式应该是后面有个空格更好,不区分大小写(因为HTML不区分大小写,通常带有大写字母标记名称),所以/<img /i
> var imgVars = emailTemplate.match(/<img[^>]+>/g);
解析HTML如果使用正则表达式不是一个好主意,将HTML转换为文档片段并处理它更好。
> var imgVars = emailTemplate.match(/<img[^>]+>/g);
注意String.prototype.match返回一个数组。
> for (i in imgVars) {
使用for..in以与阵列不推荐用于多种原因,例如可能不以任何特定次序返回的部件(其可以是不同的浏览器不同)和的for..in将返回数组中的所有枚举的属性和它的[[Prototype]]
所以如果你在浏览器中已经有Array.prototype
由“垫片”或“猴子补丁”,那么这些属性也将被列举的修改,所以:
> var title = imgVars[i].match(/title="([^\"]+\")/);
很可能会试图呼叫匹配对属性的值是一个引用因为这是一个函数,所以抛出一个错误。至少应该包括一个hasOwnProperty测试,但最好只使用plain for循环。
> for (j in attachments) {
看来附件是一个数组太多,所以使用普通的for循环在这里也以同样的理由如上述。这也不是一个好主意。(可能会以意想不到的顺序访问房产),拼接,推断您期待特定订单。请注意,在某些浏览器中,for..in会按照它们添加到数组中的顺序访问数组成员,而不是按数字顺序访问。其他浏览器将始终以特定顺序访问数字属性,但不会访问其他浏览器。
这在很大程度上会简单得多,如果HTML被转换成文档片段,然后DOM方法可以用于提取在img要素和访问他们的属性来建立一个对象。然后可以使用本地方法将对象转换为JSON(如果需要)。
草稿或罐头响应的100%保真度是完全可行的。此代码段是从工作邮件合并我扩展,以支持内嵌图像(包括嵌入式斑点和外部参考)和附件,以及:
...
//selectedTemplate is a Gmail Message (draft/canned response)
var emailTemplate = selectedTemplate.getBody();
var attachments = selectedTemplate.getAttachments();
var to = selectedTemplate.getTo();
var cc = selectedTemplate.getCc();
var bcc = Session.getActiveUser().getEmail();
if(emailTemplate.search(/<\img/ != -1)){
var inlineImages = {};
var imgVars = emailTemplate.match(/<img[^>]+>/g);
for(i in imgVars){
var title = imgVars[i].match(/title="([^\"]+\")/);
if (title) {
title = title[1].substr(0, title[1].length-1);
var titleEncoded = title.replace(/ /g,"-");
for(j in attachments){
if(attachments[j].getName() == title){
inlineImages[titleEncoded] = attachments[j].copyBlob().setName(titleEncoded);
attachments.splice(j,1);
}
}
var newImg = imgVars[i].replace(/src="[^\"]+\"/,"src=\"cid:"+titleEncoded+"\"");
emailTemplate = emailTemplate.replace(imgVars[i],newImg);
}
}
}
...
GmailApp.sendEmail(....,
{attachments: attachments, ...,
inlineImages: inlineImages});
我有这个与域用户工作了一整天,每一天。希望这可以帮助。
谢谢Peter:D!这是很好的代码,但不幸的是,内嵌图像依旧会出现在邮件正文为空白矩形。也许有什么毛病我用草案/罐头回应。 – KarBytes 2012-08-03 15:36:04
请尝试新的草案,如果问题仍然存在,编辑的问题,并张贴您所使用的代码。 – 2012-08-03 22:32:26
不幸的是,内嵌图片没有标题。他们有一个alt =嵌入式图像1,但这不同于附件的名称。 img标签中的唯一项目是alt和src。
鉴于这种情况,似乎没有被任何方式对内嵌图像领带到其他附件,而不是希望,第一个行内的图像是第一个附件等
我要指出,我使用Gmail网络界面创建草稿,并通过“插入图像”实验室插入图像。
您确定要创建** JSON **或只是一个JavaScript对象吗?你的第一个代码示例只显示一个对象。而实际上你的问题是什么?你没有问过任何问题。 – 2012-07-31 23:49:06
啊,到底是什么。让我们将对象文字重命名为JSON对象。 ':P' – 2012-08-01 01:49:52
噢,问题是如何我应该内联的图像阵列,以便它可以采取如在GmailApp.sendEmail()可选的参数的inlineImages参数格式。我不确定它是否应该是JSON或JavaScript对象,但我的猜测是它是一个JavaScript对象。 – KarBytes 2012-08-01 19:59:56