如何在ie9或ie8中通过javascript读取本地图像文件



我想在ie9或ie8中通过java脚本读取本地文件图片。这可能吗?

我只想读取对象并将其显示在我发现ie8和ie9部分支持

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAI
AAAFSDNYfAAAAaklEQVR42u3XQQrAIAwAQeP%2F%2F6wf8CJBJTK9lnQ7FpHGaOurt1
I34nfH9pMMZAZ8BwMGEvvh%2BBsJCAgICLwIOA8EBAQEBAQEBAQEBK79H5RfIQAAAAA
AAAAAAAAAAAAAAAAAAAAAAID%2FABMSqAfj%2FsLmvAAAAABJRU5ErkJggg%3D%3D">

我想读取二进制文件,并将其转换为以上形式的字符串。这样我就可以展示当地的图片。

我只想要ie8和ie9的支持。我已经完成了ff部分,客户希望支持ie8和ie9

是的,你可以(就像一些我几乎不认识的怪人会说的那样)。。。是的,您可以通过ActiveX使用FSO/OpenTextFile使用Internet Explorer以Javascript读取和写入二进制文件。事实上,我甚至写了一个Javascript">Fichier"(我是法国人)类,它允许Internet Explorer以各种模式打开本地文件,包括直接访问模式,根据需要提供Seek(位置)、Read(numberOfBytes)、Write(字符串)和Save更改。

例如,它还可以将整个文件加载到一个字符串中,并将其转换为Base-64:这允许直接从本地磁盘加载图像文件,而不是让它们由某个web服务器上传,然后下载回客户端:想想从伦敦西部到伦敦市中心,你必须先从伦敦西部到格拉斯哥,然后从格拉斯哥回到伦敦市中心?

关键是您只需要知道一个小秘密,没有这个秘密,您将无法将所有字节写入磁盘,也无法将加载的文件转换为Base-64。考虑到以下两点,我只想告诉你这个秘密:

首先,您必须逐字节读取文件,而不是readAll()或read(n),其中n>1。这样,在某些情况下可以防止浏览器关联几个字节。因此,您将创建一个包含"objectFile.Read(1)"的循环。

其次,秘密是:在ASCII+表的256个字符(扩展到第8位)中,有27个字符有异常行为,这是唯一阻止您操作二进制文件的原因:这27个字符位于2个"段落"的范围内,即从128到159(80h到9Fh)的32个字节,除了其中5个字符:129141143144157:这5个字符表现正常。但对于32范围内的其他27个字节,一旦从磁盘中读取,它们就会变为16位值:例如,在UTF-8中,欧元符号应该是128(80h)字符,实际上,它就是在文件中写入的值。但在浏览器的内存中,一旦从磁盘读取第80个字节,它就会变成一个16位的值:8364(20ACh)。

要理解这一点,请尝试以下代码,假设您可以在"D:\"目录上编写,否则请更改代码以指定另一个目录,您的浏览器有权在该目录上编写。

<script type="text/javascript'>
fso = new ActiveXObject("Scripting.FileSystemObject");
oFich = fso.OpenTextFile("d:\foo.txt", 2, true);
var c1 = String.fromCharCode(65); // 65 is the ASCII code for "A"
oFich.write(c1);
oFich.close();
</script>

执行完代码后,您会在磁盘上找到一个"foo.txt"文件:在文本板中打开它,您会看到一个完美的"a"。

现在,在上面Javascript代码的第三行,您可以用任何其他值替换值"65",例如"66"将在foo.txt文件中写入"B","97"将写入"a","55"将写入"7"等等……但现在,尝试使用值"128":这会变得不愉快,因为您正在受到浏览器的侮辱!像这样:

"Incorrect argument or procedure call"

好吧,你只想把"€"符号写进你的文件里。你为什么不能那样做?因为值128不能通过FSO按原样写入。上面提到的其他26个值也是如此。顺便说一句,不要认为是第8位导致了故障,因为128是第一个8位数字:如果你用160到255之间的任何数字替换128,也设置了第7位,你就会发现它工作得很好。

所以,现在试试这个:

fso = new ActiveXObject("Scripting.FileSystemObject");
oFich = fso.OpenTextFile("d:\foo.txt", 2, true);
var c1 = String.fromCharCode(8364); // 8364  (unicode for "€" symbol ?)
oFich.write(c1);
oFich.close();

您会很满意地注意到,在执行之后没有更多的错误消息。然后,键入你的"foo.txt",你会看到一个漂亮的"€"符号。但让你惊讶的是,如果你将该文件加载到一个十六进制的"dumper"工具中,你会发现代码不是"AC20"(8364),而是"80"(128)!

知道了这一点,您现在可以将任何字节串转换为Base-64或将任何字节字符串写入文件,只要您知道要将"128"字节写入磁盘,您就别无选择,只能用8364(20ACh)替换它。顺便说一句,如果你真的想写8364(20ACh),那没问题:但这意味着你的文件是16位值的组合,而不是简单的字节范围。因此,您只需将两个字节组合起来,首先写入低字节:

oFich.write(String.fromCharCode(172)); // 172 = ACh
oFich.write(String.fromCharCode(32));  //  32 = 20h   

就你只处理文本而言,你没有什么可做的:"€"在浏览器的内存和磁盘上的写入方式不同,但它仍然是"€",所以它是透明的。但是,如果你加载字节128作为它的数值,那么,你就会遇到问题,因为你会得到8364,而不是从文件中读取的每128个:这就是为什么很多人在尝试用Javascript编码base-64时失败的原因。

事实上,当你想让27个dooming字符取其数值时,你只需要过滤它们。这就是为什么我写了以下两个函数,我在">Fichier"类的某些部分中使用它们,在需要它们的地方,以及在Base-64算法中,当我直接从客户端磁盘加载图像文件时,或者当我必须将字节作为数字而非字符进行操作时:

这两个函数抵消了它们的Javascript模型的部分">变态":

`String.fromCharcode() and String.charCodeAt()`

由于它们只是简单地封装了它们的模型,我给它们起了经典的基本名称:"asc"one_answers"chr",所以它们既易于理解又易于记忆。它们在这里:

function asc(c) //(string)->integer
{   // Objet : Renvoie le code ASCII du 1er caractère de la chaine "c"
var i = c.charCodeAt(0);
if (i < 256)
return i;       // caractères ordinaires
// (plage 128-159 excepté les 5 caractères 129,141,143,144,157, qui fonctionnent normalement)
switch (i) {
case 8364:      // "€" 
return 128
case 8218:
return 130
case 402:
return 131
case 8222:
return 132
case 8230:
return 133
case 8224:
return 134
case 8225:
return 135
case 710:
return 136
case 8240:
return 137
case 352:
return 138
case 8249:
return 139
case 338:
return 140
case 381:
return 142
case 8216:
return 145
case 8217:
return 146
case 8220:
return 147
case 8221:
return 148
case 8226:
return 149
case 8211:
return 150
case 8212:
return 151
case 732:
return 152
case 8482:
return 153
case 353:
return 154
case 8250:
return 155
case 339:
return 156
case 382:
return 158
case 376:
return 159
default:
return -1       // provoquera une erreur, le cas ne devant pas se présenter
}
}
function chr(octet) //->(integer)->string
{   // Objet  : renvoie le caractère d'un nombre 8 bits
// Entrée : "octet" est un nombre 8 bits non signé (entre 0 et 255)
// Sortie : le caractère correspondant est renvoyé, les codes échappés sont rattrapés par un switch
if (octet < 128) || (octet > 159))
return String.fromCharCode(octet);     // caractères ordinaires, traités par String.fromCharCode
switch (octet) {
case 128:
return "€"
case 129:
return String.fromCharCode(129);
case 130:
return "‚"
case 131:
return "ƒ"
case 132:
return "„"
case 133:
return "…"
case 134:
return "†"
case 135:
return "‡"
case 136:
return "ˆ"
case 137:
return "‰"
case 138:
return "Š"
case 139:
return "‹"
case 140:
return "Œ"
case 141:
return String.fromCharCode(141);
case 142:
return "Ž"
case 143:
return String.fromCharCode(143);
case 144:
return String.fromCharCode(144);
case 145:
return "‘"
case 146:
return "’"
case 147:
return "“"
case 148:
return "”"
case 149:
return "•"
case 150:
return "–"
case 151:
return "—"
case 152:
return "˜"
case 153:
return "™"
case 154:
return "š"
case 155:
return "›"
case 156:
return "œ"
case 157:
return String.fromCharCode(157);
case 158:
return "ž"
case 159:
return "Ÿ"
default:
return String.fromCharCode(octet);         // unicode 16 bits
}
}

现在,您可以使用ActiveX在磁盘的每个允许IE访问文件的区域使用Internet Explorer对任何类型的文件进行二进制读写。

正如伟大而令人怀念的法国幽默作家皮埃尔·德斯普罗格斯曾经说过的那样:"埃顿南特,不是吗?">

BB。

出于安全原因,JavaScript没有此功能。

因为我们正在访问本地文件系统。因此,出于安全原因,我们无法在JavaScript中看到文件夹结构或上传的文件路径。

为了扩展David的评论,MS承诺支持IE10的FileAPI标准。浏览器包的其余部分在HTML5上遥遥领先。

对于IE8-9,您可能需要使用ActiveX或Flash的SWFObject 之类的插件

最新更新