过于脆弱,
// 一旦有人为可读性加上该标志即退化为存储型 XSS。
var peaks = [{"t":27.6167,"i":3.2363,"hkl":"(2,0,-2,0)","d":3.23},{"t":33.3786,"i":23.6135,"hkl":"(2,0,-2,1)","d":2.68443},{"t":36.8107,"i":38.9389,"hkl":"(3,-1,-2,0)","d":2.44165},{"t":37.2558,"i":24.7759,"hkl":"(0,0,0,2)","d":2.41349},{"t":39.8739,"i":38.7525,"hkl":"(1,0,-1,2)","d":2.26086},{"t":41.4439,"i":100,"hkl":"(3,-1,-2,1)","d":2.17877},{"t":41.4439,"i":50,"hkl":"(2,1,-3,1)","d":2.17877},{"t":41.9564,"i":11.2575,"hkl":"(3,0,-3,0)","d":2.15333},{"t":44.7251,"i":3.8496,"hkl":"(2,-1,-1,2)","d":2.02625},{"t":46.1606,"i":21.8983,"hkl":"(3,0,-3,1)","d":1.96653},{"t":46.9992,"i":6.3547,"hkl":"(2,-2,0,2)","d":1.93338},{"t":46.9992,"i":12.7095,"hkl":"(2,0,-2,2)","d":1.93338},{"t":48.8369,"i":14.74,"hkl":"(4,-2,-2,0)","d":1.86484},{"t":53.3761,"i":3.9831,"hkl":"(3,-2,-1,2)","d":1.71646},{"t":53.3761,"i":7.9661,"hkl":"(3,-1,-2,2)","d":1.71646},{"t":54.6403,"i":1.7726,"hkl":"(4,-3,-1,1)","d":1.6797},{"t":54.6403,"i":3.5452,"hkl":"(4,-1,-3,1)","d":1.6797},{"t":57.025,"i":1.2459,"hkl":"(4,0,-4,0)","d":1.615},{"t":57.344,"i":5.1914,"hkl":"(3,0,-3,2)","d":1.60677},{"t":60.445,"i":2.6487,"hkl":"(4,-4,0,1)","d":1.53155},{"t":60.445,"i":5.2973,"hkl":"(4,0,-4,1)","d":1.53155},{"t":62.99,"i":3.1789,"hkl":"(4,-2,-2,2)","d":1.47566},{"t":62.99,"i":1.5894,"hkl":"(2,2,-4,2)","d":1.47566},{"t":64.7269,"i":11.3917,"hkl":"(2,0,-2,3)","d":1.4402},{"t":65.9327,"i":2.5322,"hkl":"(5,-2,-3,1)","d":1.41675},{"t":65.9327,"i":1.2661,"hkl":"(3,2,-5,1)","d":1.41675},{"t":66.3056,"i":1.0322,"hkl":"(5,-1,-4,0)","d":1.40969},{"t":69.4611,"i":1.138,"hkl":"(5,-1,-4,1)","d":1.35316},{"t":70.0326,"i":4.35,"hkl":"(3,-1,-2,3)","d":1.34351},{"t":73.2661,"i":1.6392,"hkl":"(5,-5,0,0)","d":1.292},{"t":73.2661,"i":3.2785,"hkl":"(5,0,-5,0)","d":1.292},{"t":73.4699,"i":8.2399,"hkl":"(3,-3,0,3)","d":1.28892},{"t":73.4699,"i":16.4796,"hkl":"(3,0,-3,3)","d":1.28892},{"t":75.2403,"i":13.3762,"hkl":"(5,-2,-3,2)","d":1.26293},{"t":75.2403,"i":6.6881,"hkl":"(3,2,-5,2)","d":1.26293},{"t":76.2956,"i":7.9565,"hkl":"(5,-5,0,1)","d":1.24806},{"t":76.2956,"i":15.9128,"hkl":"(5,0,-5,1)","d":1.24806},{"t":76.6463,"i":12.2796,"hkl":"(6,-3,-3,0)","d":1.24323},{"t":76.6463,"i":6.1398,"hkl":"(3,3,-6,0)","d":1.24323},{"t":78.5917,"i":1.3351,"hkl":"(5,-1,-4,2)","d":1.21726},{"t":80.178,"i":2.561,"hkl":"(4,-1,-3,3)","d":1.19712},{"t":80.178,"i":1.2805,"hkl":"(3,1,-4,3)","d":1.19712},{"t":81.0671,"i":7.1702,"hkl":"(1,0,-1,4)","d":1.18623},{"t":85.116,"i":1.9816,"hkl":"(4,0,-4,3)","d":1.13985},{"t":85.1891,"i":1.1092,"hkl":"(5,-5,0,2)","d":1.13906},{"t":85.1891,"i":2.2185,"hkl":"(5,0,-5,2)","d":1.13906},{"t":85.9958,"i":4.4108,"hkl":"(2,0,-2,4)","d":1.13043},{"t":86.2149,"i":1.3559,"hkl":"(6,-1,-5,1)","d":1.12812},{"t":88.4585,"i":6.8582,"hkl":"(6,-3,-3,2)","d":1.10521},{"t":88.4585,"i":3.4291,"hkl":"(3,3,-6,2)","d":1.10521}];
// 图例文案(中文站字面量;英文站模板传英文,见 en/page/detail.php)
var LBL_MATERIAL_PEAK = '材料衍射峰';
var initialRadiation = 'Cu Kα';
var canvas = document.getElementById('xrd-detail-canvas');
var note = document.getElementById('xrd-note');
var body = document.getElementById('xrd-peaks-body');
var cnt = document.getElementById('xrd-peaks-count');
var sel = document.getElementById('xrd-target');
var link = document.getElementById('xrd-direct-link');
var mpId = "mp-1106065";
function renderChart(ps, radiation) {
if (typeof XrdChart === 'undefined' || !canvas || !Array.isArray(ps)) return;
var m = 0;
ps.forEach(function (p) { if (p.t > m) m = p.t; });
var mt = Math.max(90, Math.ceil((m + 5) / 10) * 10);
XrdChart.render(canvas, { materialPeaks: ps, label: radiation, maxTheta: mt, materialPeakLabel: LBL_MATERIAL_PEAK });
}
function renderTable(ps) {
if (!body) return;
var rows = '';
ps.slice(0, 24).forEach(function (pk) {
var t = (pk.t != null) ? Number(pk.t).toFixed(2) : '';
var d = (pk.d != null) ? Number(pk.d).toFixed(4) : '';
var i = (pk.i != null) ? Number(pk.i).toFixed(1) : '';
var h = (pk.hkl != null) ? String(pk.hkl).replace(/[<>&]/g, '') : '';
rows += '
' + t + '
' + d + '
' + i + '
' + h + '
';
});
body.innerHTML = rows;
if (cnt) cnt.textContent = Math.min(ps.length, 24);
}
function updateLink(target) {
if (link) link.href = location.origin + '/api/v1/materials/' + encodeURIComponent(mpId) + '/xrd?format=raw&target=' + encodeURIComponent(target);
}
// 初始渲染(服务端已预取默认靶材的图谱)
renderChart(peaks, initialRadiation);
if (sel) updateLink(sel.value);
// 切换靶材:重新拉取该靶材的衍射图谱并刷新图表 / 表格 / 直接链接
if (sel) {
var xrdSeq = 0;
sel.addEventListener('change', function () {
var t = sel.value;
updateLink(t);
var my = ++xrdSeq;
// 先清空 loading 态,避免请求失败后按钮一直停在“切换中”
if (note) note.textContent = '正在加载 ' + t + ' 图谱…';
fetch('/api/v1/materials/' + encodeURIComponent(mpId) + '/xrd?target=' + encodeURIComponent(t))
.then(function (r) {
if (!r.ok) throw new Error('HTTP ' + r.status);
return r.json();
})
.then(function (res) {
// 竞态防护:快速切换靶材时,先发的请求可能后到,丢弃过期响应
if (my !== xrdSeq) return;
if (!res.success || !res.data || !Array.isArray(res.data.peaks) || !res.data.peaks.length) {
throw new Error(res.error || '该靶材暂无衍射数据');
}
var d = res.data;
if (note) note.textContent = '横轴为 2θ (°),纵轴为相对强度,' + d.radiation + ' , λ=' + d.wavelength + ' Å';
renderChart(d.peaks, d.radiation);
renderTable(d.peaks);
})
.catch(function (e) {
if (my !== xrdSeq) return;
// 恢复服务端预取的默认靶材视图,并明确提示失败原因
// (旧实现是空 catch,静默失败会让图表停留在上一个靶材的数据而用户毫不知情)
if (note) note.textContent = '切换靶材失败:' + (e && e.message ? e.message : '未知错误');
renderChart(peaks, initialRadiation);
renderTable(peaks);
});
});
}
})();
The crystal structure and related material properties of B3Rh7 were obtained from the Materials Project database (MP-ID: mp-1106065, database version v2026.04.13).
文献引用
Horton, M.K., Huck, P., Yang, R.X. et al. Accelerated data-driven materials science with the Materials Project. Nat. Mater. 24, 1522–1532 (2025).
https://doi.org/10.1038/s41563-025-02272-0