繁体   English   中英

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

[英]How to read the local image file via javascript in ie9 or ie8?

我想通过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

是的你可以(因为我不知道会有什么奇怪的人会说)...是的你可以使用FSO / OpenTextFile通过ActiveX在Internet Explorer中使用Javascript读取和编写二进制文件。 实际上,我甚至编写了一个Javascript“ Fichier ”(我是法语)类,它允许Internet Explorer以各种模式打开本地文件,包括直接访问模式,提供Seek(位置),Read(numberOfBytes),Write(string) ,并根据需要保存更改。

例如,它还可以将整个文件加载到字符串中并将其转换为Base-64:这允许直接从本地磁盘加载图像文件,而不是让它们被某些Web服务器上载并随后下载回客户端:确实不是很奇怪,想到从伦敦西部到伦敦市中心,你有义务先从伦敦西部去格拉斯哥,然后从格拉斯哥回到伦敦市中心吗?

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

首先,您必须逐字节读取文件,而不是readAll()或read(n),其中n> 1。 这样,在某些情况下,您可以防止浏览器关联多个字节。 所以你将在里面用“objectFile.Read(1)”做一个循环。

其次,这是秘密:在ASCII +表的256个字符(扩展到第8位)中,其中27个具有异常行为,这是唯一阻止您操作二进制文件的行为:这27个字符位于该范围内2个“段落”,即32个字节,从128到159(80h到9Fh),除了5个:129,141,143,144,157:这5个表现正常。 但对于该范围32的其他27个字节,只要从磁盘读取它们,就会将它们更改为16位值:例如,欧元符号应该是UTF中的字符128(80h)实际上,它是在文件中写入的值。 但是在浏览器的内存中,只要从磁盘读取80h字节,就会变为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代码的第3行,您可以将值“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”,您将看到一个漂亮的“€”符号。 但令您惊讶的是,如果您将该文件加载到十六进制“转储器”工具中,您将看到代码不是“AC 20”(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个字符。 这就是为什么我编写了以下两个函数,我在我的“ Fichier ”类的某些部分使用它们,在我的Base-64算法中,当我直接从客户端磁盘加载图像文件时,或者当我必须将字节操作为数字而不是字符时:

这两个函数抵消了他们的Javascript模型的部分“ 变态 ”:

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

由于他们只是封装了他们的模型,我给了他们经典的基本名称:“asc”和“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
    }
}

现在,您可以在允许IE浏览文件的磁盘的每个区域上使用ActiveX二进制读取和写入任何类型的文件。

正如伟大而错过的法国幽默家皮埃尔·德斯普罗格曾经说过的那样:“ Etonnant,不是吗?

BB。

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

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

扩展David的评论 - MS承诺支持IE10的FileAPI标准。 浏览器包的其余部分远远领先于HTML5。

对于IE8-9,你可能不得不使用像ActiveX或Flash的SWFObject这样的插件

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM