1

我想通过 ie9 或 ie8 中的 java-script 读取本地文件图片。那可能吗?

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

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

我想读取二进制文件并将其转换为上面的表单字符串。这样我就可以显示本地图片。

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

4

3 回答 3

2

是的,你可以(就像我几乎不知道的一些奇怪的人会说的那样)... 是的,你可以通过 ActiveX使用FSO/OpenTextFile使用 Internet Explorer 在 Javascript 中读取和写入二进制文件。事实上,我什至写了一个 Javascript “ Fichier ”(我是法国人)类,它允许 Internet Explorer 以各种模式打开本地文件,包括直接访问模式,提供 Seek(position)、Read(numberOfBytes)、Write(string)和按需保存更改。

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

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

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

. 其次,这是秘密:在 ASCII+ 表的 256 个字符中(扩展至第 8 位),其中 27 个具有异常行为,这是阻止您操作二进制文件的唯一因素:这 27 个字符位于范围内2个“段落”,即从128到159(80h到9Fh)的32个字节,其中5个除外:129,141,143,144,157:这5个行为正常。但是对于 32 范围内的其他 27 个字节,一旦从磁盘中读取它们,它们就会被更改为 16 位值:例如,欧元符号应该是 UTF- 中的字符 128 (80h) 8,它确实是写入文件中的值。但是在浏览器的内存中,一旦你从磁盘中读取了 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”将“B”写入 foo.txt 文件,“97”将写入“a”, “55”会写成“7”等等……但是现在,用值“128”试试吧:它变得不愉快,因为你被浏览器侮辱了!像这样:

                    "Incorrect argument or procedure call"

好吧,您想要的只是将“€”符号写入您的文件中。为什么你不能这样做?因为值 128 不能通过 FSO 写入。上面提到的其他 26 个值也是如此。顺便说一句,不要断定是第 8 位导致该故障,因为 128 是前 8 位数字:如果您将 128 替换为 160 到 255 之间的任何数字,也设置了第 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()`

因为他们只是简单地封装了他们的模型,所以我给了他们经典的 Basic 名称:“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
    }
}

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

正如伟大而怀念的法国幽默家 Pierre Desproges 曾经说过的那样:“ Etonnant,非?

BB。

于 2014-09-27T23:49:32.657 回答
1

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

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

于 2012-10-19T20:05:05.477 回答
0

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

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

于 2014-01-17T19:33:45.100 回答