我们有一个用Angular4+编写的Web-email-client。我们从 Exchange Web 服务加载电子邮件。
传入邮件经过清理,然后呈现为 iframe 的源。即使对于图像,这也工作正常,除了它们被嵌入为类似
<img width="486" height="572" id="Grafik_x0020_2" src="cid:image002.jpg@01D39103.BD805530">
有没有办法在渲染电子邮件时显示图像?我们也可以下载附件。
感谢和最诚挚的问候克里斯托夫
因为我们已经下载了附件,我写了一个管道来解决这个问题:
import { Pipe, PipeTransform } from '@angular/core';
import { TrusthtmlPipe } from 'app/crm-modules/core/pipes/trusthtmlPipe';
import { DomSanitizer } from '@angular/platform-browser';
import { SafeHtml } from '@angular/platform-browser/src/security/dom_sanitization_service';
import { AttachmentInfo } from 'app/crm-modules/email/models/attachment-info';
import * as _ from 'lodash';
@Pipe({
name: 'cidToBase64'
})
export class CidToBase64Pipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {
this.sanitizer = sanitizer;
}
transform(html: any, attachments: Array<AttachmentInfo> = []): SafeHtml {
let htmlToParse;
if (typeof html === 'string') {
htmlToParse = html;
} else if (html instanceof Object && html.hasOwnProperty('changingThisBreaksApplicationSecurity')) {
htmlToParse = (html.changingThisBreaksApplicationSecurity !== null || html.changingThisBreaksApplicationSecurity !== undefined)
? html.changingThisBreaksApplicationSecurity
: '';
} else {
htmlToParse = '';
}
const parser = new DOMParser();
const doc = parser.parseFromString(htmlToParse, 'text/html');
if (attachments !== null && attachments !== undefined && attachments.length > 0 && htmlToParse.length > 0) {
const imageLinks = doc.getElementsByTagName('img');
for (let i = 0; i < imageLinks.length; i++) {
const imageLink = imageLinks[i];
const src = imageLink.getAttribute('src');
if (src !== null && src !== undefined && _.includes(src, 'cid:')) {
let cidInfo;
let fileName;
let fileIndex;
let useImage = true;
cidInfo = src.split('cid:');
useImage = cidInfo.length === 2;
if (useImage) {
fileName = cidInfo[1].split('@')[0];
fileIndex = _.findIndex(attachments, { 'name': fileName, 'inline': true });
useImage = fileIndex > -1;
}
if (useImage) {
imageLink.setAttribute('src', 'data:image/png;base64,' + attachments[fileIndex].content);
} else {
// @todo: show placeholder or remove the node...
}
}
}
}
const trustHtmlPipe = new TrusthtmlPipe(this.sanitizer);
return trustHtmlPipe.transform(doc.documentElement.innerHTML);
}
}
也许它有帮助。
此致敬意克里斯托夫
感谢您的代码。我重写了你的管道以自己使用它,我认为它更通用一些,所以我把它留在这里,以防有人发现它有用:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'cidToBase64'
})
export class CidToBase64Pipe implements PipeTransform {
parser : DOMParser = new DOMParser();
constructor() {
}
transform(html: String, attachments: Attachment[]): String {
if (html.length <= 0) {
return "";
}
if (attachments == null || attachments == undefined || attachments.length < 0) {
return "";
}
const doc = this.parser.parseFromString(html.toString(), 'text/html');
const imageLinks = doc.getElementsByTagName('img');
for (let i = 0; i < imageLinks.length; i++) {
const src = imageLinks[i].getAttribute('src');
if (src !== null && src !== undefined && src.includes('cid:')) {
let attachmentContent = src.split('cid:')[1].split('@')[0];
let fileIndex = attachments.findIndex(obj => obj.Name === attachmentContent);
imageLinks[i].setAttribute('src', 'data:image/png;base64,' + attachments[fileIndex].Content);
html = html.replace(src, imageLinks[i].getAttribute('src'));
}
}
return html;
}
}
export interface Attachment {
Content: String;
ContentLength: Number;
Name: String;
ContentType: String;
ContentID: String;
}
然后,您可以在.html中将其用作任何其他管道:
<p [innerHTML]="mail.HtmlBody | cidToBase64 : mail.Attachments"></p>