【问题标题】:Data URIs causing syntax errors in Javascript在 Javascript 中导致语法错误的数据 URI
【发布时间】:2013-07-25 21:31:18
【问题描述】:

我正在尝试使用数据 URI 在画布元素内绘制图像。我正在使用 Django 并将包含照片的 base64 编码的变量传递给模板。过去,我是这样使用的:

<img src="data:image/jpg;base64, {{ photo_data }}">

这很好用。我现在想用这个替换它:

<canvas id="canvas"></canvas>

并使用 javascript 在画布中绘制图像。我试用了this answer的代码:

var canvas = $('#canvas');
var ctx = canvas.getContext('2d');
var img = new Image;
$(img).load(function(){
    ctx.drawImage(img, 0, 0);
});
img.src = "data:image/jpg;base64, {{ photo_data }}"

这给了我最后一行的 javascript 错误“SyntaxError: unterminated string literal”。我读到这个错误通常是由于换行符而发生的。在检查页面源代码时,看起来那里有换行符:

然后我尝试删除换行符:

function removeBreaks(data){
    return data.replace(/(\r\n|\n|\r)/gm, "");
}

var photo_data = removeBreaks({{ photo_data }});

现在我在调用 removeBreaks 时遇到了一个新错误。 “SyntaxError:标识符在数字文字之后立即开始”。

var photo_data = removeBreaks(/9j/4AAQSkZ...
----------------------------------^

我是否需要进行某种转义,如果需要,我该怎么做?

更新

我尝试了 cmets 的所有建议和答案。到目前为止,最接近工作的事情正在做

photo_data = json.dumps(<base64 encoded image file>)

在 Django 方面和

var photo_data = "{{ photo_data }}".replace(/&quot;/g,"");
img.src = "data:image/jpg;base64, " + photo_data;

在 Javascript 方面。如果我不替换&amp;quot;s,图像根本不会显示,当我删除它们时,只显示图像的前三分之一。我尝试调整画布元素的大小,这似乎不是问题。

更新 #2

原来画布大小是问题所在。画布元素的宽度和高度需要与图像的宽度和高度一样大或更大,这是我在创建Image 对象时没有设置的。接受的答案和 json.dumps(带有 &amp;quot; 警告)都可以解决原始问题。

【问题讨论】:

  • 试试removeBreaks("{{ photo_data }}");
  • 我做到了,这又给出了“未终止的字符串文字”错误。
  • 您将不得不转换该文本块,以便将真正的换行符替换为 \n - 一个反斜杠和一个“n”,这是 JavaScript 期望换行符编码的方式在字符串中。您必须在 Django 端进行,而不是在 JavaScript 端。
  • 尝试使用 JSON 编码器函数对图像数据进行编码。然后将数据 URL 标头添加到该标题中。可能是img.src = "data:image/jpg;base64, " + {{ json.dumps(photo_data) }}; 之类的东西(我不是 Python 程序员)。
  • 您的多行数据字符串导致语法错误。您期望 JavaScript 通过将语法损坏的字符串传递给 JavaScript 函数来清理它。该 JavaScript 函数无法运行,因为在其调用中存在语法错误(由多行字符串引起)。相反,您必须在生成 JavaScript 字符串的服务器端代码中修复此问题。 Django 是首先将换行符放在那里的系统;肯定 Django 有一些功能可以消除它们吗?

标签: javascript django data-uri


【解决方案1】:

我是这样做的:

img.src = "1234 ... 56789" + //
   "01234567 ... 7890" + //
   .....
   "67879878907890";

与我一起工作的一些人喜欢将+ 放在行首,声称它更易于阅读。

假设您有图像数据,base64 编码在一个字符串中。一种类似于伪 C/Java/Javascript 的语言会有这样的代码(因为我不懂 Python):

String image64 = ...
String output = "img.src = \"data:image/jpg;base64, ";

for (int i = 0; i < image64.length ; i += 100) {
    if (i > 0) {
        output += "\" + // \n    \"";
    }
    if (i + 100 < image64.length) {
        output += image64.substring(i, i+100);
    } else {
        output += image64.substring(i); // this gets the rest
    }
}
output += "\";\n";

然后您将output 的值写入您放置 javascript 的位置。

现在快速浏览一下 Django 和 Python 的东西让我怀疑它在模板中看起来像这样:

img.src = "data:image/jpg;base64, " + //
{% for line in photo_data_lines %}
    "{{ line }}" + //
{% endfor %}
    "";

但您必须事先在每个元素中设置 photo_data_lines 数组,其中包含 100 个字符的图像数据块。 (或者无论你想要多长的块。)

【讨论】:

  • 在这种情况下,图像数据不是作为文字存在的,而是在 Python 字符串(或类似的东西)中。正在生成 JavaScript。
  • 让 Python 从图像中写入 100 个字符,然后 " + // \n\t" 使其正确写入 javascript。您正在使用 Python 编写 Javascript,并且它必须是有效的。
  • 是的,这可行,但我敢打赌 Python JSON 编码器会将嵌入的换行符转换为 \n 转义符。
  • 因为这是一种简单的方法来清理字符串以包含在 JavaScript 源代码中。任何语法上有效的 JSON 也是有效的 JavaScript。
  • 那么...您是否希望在图像的 base64 渲染中出现时髦的字符?人物内容极其有限。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-14
  • 2014-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 2017-04-01
相关资源
最近更新 更多