none
IE8で日本語ファイル名の画像について名前をつけて保存しようとすると untitled.bmp になり bmp でしか保存できない RRS feed

  • 質問

  • IE8で、日本語ファイル名の画像を
    名前をつけて保存しようとすると
    ファイル名がuntitled.bmp になり bmp でしか保存できません

    インターネット一時ファイルをクリアしても解消しません。

    英数字のファイル名は問題なく動作します。
    (ファイル名も保存した画像形式ももとのまま)

    お手数お掛け致しますが、どなたか適用方法をご存知でしたら、適用方法をご教示願います。
    宜しく御願い致します。
    2009年9月29日 5:07

回答

  • index.datは、URLで検索すると、キャッシュのディレクトリ番号とファイル名を返すようなデータ構造です。
    index.datをメモ帳で開いて、URLの前半で検索すると、後半がどういうエンコードになっているか見て分かります。
    中身をまともに見てなかったんですが、今回確認しました。
    確かに、index.datファイル内にutf8バイナリで保存されているものと
    utf8をURLエンコードしたものが保存されていることを確認しました。


    GetUrlCacheEntryInfoW/Aが、そのまさかみたいです。


    おお、すばらしいですね!
    おかげでデバッグ版wininet.dllの存在を思い出しました。このdllはAPIの呼び出し履歴をファイルとして吐いてくれます。
    そこで色々確認してみました(IE7ですが。IE8対応のデバッグ版wininet.dllはまだ見当たらないので)

    ●●APIについて●●
    キャッシュを保存したい時が
    SetUrlCacheEntryInfoで
    普通にブラウザのキャッシュを探したいときが
    GetUrlCacheEntryInfoで
    名前を付けてファイルを保存のときは
    RetrieveUrlCacheEntryFile
    ではないかと思いました。
    (どちらもINTERNET_CACHE_ENTRY_INFO構造体を得る為のAPIのようですが。。)


    ●●デバッグログがどのように出力されたかの概略●●
    【<img src="あ.jpg">】が書かれたHTMLファイルを表示するケース

    ファイル名がutf8状態でSetUrlCacheEntryInfoAの第1引数に渡される(index.datと同様)
      SetUrlCacheEntryInfoA("http://hogehoge/あ.jpg", 0x4edec60, 4608)
                         ↑上記の「あ」の部分は実際はutf8です。

    上記状態で右クリック「名前を付けてファイルを保存」とすると
    ファイル名がshift-jis状態でRetrieveUrlCacheEntryFileAの第1引数に渡されていました。
      RetrieveUrlCacheEntryFileA("http://hogehoge/あ.jpg", 0x4557bc8, 0x45579b0, 0x0)
        RetrieveUrlCacheEntryFileA() returning 2 [ERROR_FILE_NOT_FOUND]
      RetrieveUrlCacheEntryFileA() returning FALSE

    結果、ファイル保存ダイアログのファイル名はuntitled.bmpになりました。


    【<img src="%E3%81%82.jpg">】が書かれたhtmlファイルを表示するケース
    すでにキャッシュにあるせいか、画面を出してもSetUrlCacheEntryInfoは呼び出されず。

    上記状態で、「名前を付けてファイルを保存」した場合
      RetrieveUrlCacheEntryFileA("http://hogehoge/%E3%81%82.jpg", 0x4557bc8, 0x45579b0, 0x0)
      RetrieveUrlCacheEntryFileA() returning TRUE

    →結果、ファイル保存ダイアログのファイル名は%E3%81%82.jpgになる(IE7なので)


    ●●対応案?●●
    ログを眺める限り、IEの内部的にはHttpOpenRequestWに渡す文字列次第で
    SetUrlCacheEntryInfoAへ渡す文字列が決まる(index.datへの内容が決まる)ように見えました。
    おそらく、IE的にはこの動きは外せないんじゃないかと思いました。
    (エンコードされているかどうかでキャッシュを分ける為にです。なぜ分ける必要があるかは分かっていませんが。)
    で、右クリックでファイルへ保存のみの動作がおかしいことを考えると、そのタイミングで呼び出すAPIを
    RetrieveUrlCacheEntryFileA→RetrieveUrlCacheEntryFileWへ変更するだけで、
    対応可能なのではと思えてきました(むしろHttpOpenRequestWと連動するようになればよい?)。
    この実現をサーバ側で制御出来ればよいのですが。。。

    2009年10月1日 18:12

  • index.datは、URLで検索すると、キャッシュのディレクトリ番号とファイル名を返すようなデータ構造です。
    index.datをメモ帳で開いて、URLの前半で検索すると、後半がどういうエンコードになっているか見て分かります。

    ③が使えない訳ではないようです。オフラインでキャッシュから読めます。
    IEが読むときには、見つかる。IEが保存するときには、見つからない。
    読むときと保存するときで、IEが使用しているインターフェースが違うとか。
    まさかと思いますが、例えば、~W()はUTF-8で検索して見つかる。~A()はシフトJISで検索して見つからないとか。

    GetUrlCacheEntryInfoW/Aが、そのまさかみたいです。

    2009年10月1日 5:53

すべての返信

  • ありがとうございます。

    代替の1つ目のリンクはすでにおこなっているのですが(リンクしている状態で右クリックで保存)、やはり
    クリック後の開いた(たとえば別ウィンドで画像ファイルをIEで開いた)後に保存したいのです。
    2つ目のリンクもそうですが
    おこないたいのは、こちらのASPやASP.NETでの制御ではなく
    制御しているページからリンクしているところをクリック後の
    IEが画像ファイルを表示している常態(urlで△△.jpg)で保存できればと考えております。
    firefoxなど他のブラウザでは問題なくできるのですが、
    社内のシステムはIEでの動作をベースにしているので、なんとかIEで実現したいのです。

    お手数お掛け致しますが、どなたか適用方法をご存知でしたら、適用方法をご教示願います。
    宜しく御願い致します。
    2009年9月29日 8:45
  • IE8で、日本語ファイル名の画像を
    名前をつけて保存しようとすると
    ファイル名がuntitled.bmp になり bmp でしか保存できません

    よく意味がわかりません。

    「日本語ファイル名の画像」ということは、サーバーに日本語のファイル名で保存されているということでしょうか。つまり、「名前を付けて画像を保存」を選択すると、デフォルトのファイル名が日本語だということでしょうか。

    「bmp でしか保存できません」というのは、どういうことでしょう?bmp の画像を bmp で保存する。何かいけないのでしょうか?

    「ファイル名が untitled.bmp になり」というのは、「名前を付けて保存」のダイアログで、どんな名前を付けても、必ず「untitled.bmp」になる、ということでしょうか?


    Windows Vista (Japanese) SP1 + IE8 で、英文字ファイル名の GIF ファイルに日本語ファイル名を付けて BMP 形式で保存しましたが、期待通りになります。


    Jitta@わんくま同盟
    2009年9月29日 13:07
  • IE8で、日本語ファイル名の画像を
    名前をつけて保存しようとすると
    ファイル名がuntitled.bmp になり bmp でしか保存できません

    どのような日本語ファイル名の画像も同じ現象なのでしょうか。例えば (利用できるなら) 自前の Web サーバーに新規にそうした画像とページを作っても、同じ現象なのでしょうか。
    もし特定の画像でしか現象が確認できないのであれば、やはりよくあるキャッシュの破損だと思います。UI からの一時ファイルの削除ではなく、Temporary Internet Files をフォルダごと再構成すると良いでしょう。

    hebikuzure
    2009年9月29日 15:12
    モデレータ
  • 頻出ネタですよね!
    こちらもIE6やIE7時において複数台のクライアントマシンで、再現していたことを確認したことはあります。
    (Webサーバを変えても同じく再現していました。再現率も100%の確率です。)
    もちろん「Temporary Internet Files をフォルダごと再構成」しても再現していました。
    以下の⑤のケースでは直ることもあるらしいですが、実はそれでは直らないケースがほとんどじゃないかと思っています。
    IE8では未確認です。

    てっきりIE8ではこの現象は直っていると認識していましたがそうではないのでしょうか。
    前提として画像を返却するときのHTTPヘッダのキャッシュ指定は、no-cacheは指定していないでよいでしょうか。
    その上で、untitled.bmpになってしまうのであれば、
    imgタグのsrcにファイル名を埋め込むときに、ファイル名をURLエンコードしてみるとよいかもしれません。
    (②によるとIE8はURLデコードされた状態でファイル名を保存出来たことがある模様なので)

    ①画像を保存するときの拡張子が変化する
    http://social.technet.microsoft.com/forums/ja-JP/internetexplorerja/thread/b6f83d17-0ce5-4f00-9312-661b64687b16/

    ②画像を保存するときにファイル名が日本語のときに拡張子がbmpになる
    http://social.technet.microsoft.com/Forums/ja-JP/internetexplorerja/thread/443570b8-8e25-4898-b8ec-83ed219be7a2

    ③Internet Explorer でグラフィック データ ファイルが適切な形式で保存されない
    http://support.microsoft.com/kb/260650/ja
     
    ④Internet Explorer で画像がビットマップ (.bmp ファイル) として保存される
    http://support.microsoft.com/kb/810978/ja

    ⑤「名前を付けて画像を保存する」について
    http://questionbox.jp.msn.com/qa26319.html
    2009年9月29日 23:37
  • imgタグのsrcにファイル名を埋め込むときに、ファイル名をURLエンコードしてみるとよいかもしれません。
    (②によるとIE8はURLデコードされた状態でファイル名を保存出来たことがある模様なので)
    切り詰め~1.JPG みたいな短いファイル名になるので、それでよければですね。

    現象を確認したい方はこちら。
    http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:%E5%AE%87%E9%83%BD%E5%AE%AE%E9%A4%83%E5%AD%90%E5%83%8F.jpg
    右クリック「名前を付けて画像を保存」 → 短いファイル名
    右クリック「対象を保存」 → 日本語ファイル名
    クリックして画像だけを表示、「名前を付けて保存」 → 短いファイル名

    さらに質問者の現象を確認したい方はこちら。
    ttp://upload.wikimedia.org/wikipedia/ja/7/73/宇都宮餃子像.jpg
    「名前を付けて保存」 → untitled.bmp
    2009年9月30日 5:25
  • 確かに Vista + IE8 でも再現しますねえ。

    http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:%E5%AE%87%E9%83%BD%E5%AE%AE%E9%A4%83%E5%AD%90%E5%83%8F.jpg

    の場合も、

    Http://upload.wikimedia.org/wikipedia/ja/7/73/宇都宮餃子像.jpg

    の場合も、 IE8 ならキャッシュには 宇都宮餃子像[1].jpg というファイル名で一時ファイルが作成される事は確認できました。
    ([1] の部分は可変ですが)
    ファイル名が正しく取得できていないという事でも無いようで、untitled.bmp になる動作は不審ですね。やはり index.dat のキャッシュデータベースと実際のキャッシュの紐付けに (何かの条件で) 問題が生じるのでしょうかね。

    hebikuzre

    2009年9月30日 13:59
    モデレータ
  • なるほど。こちらでもウィンドウズスクリプトプログラマさんの言うとおりになりました。
    URLの送信方法や保存方法によって、日本語画像の保存はIE8では3パターンに分かれるんですね。
    まとめ方を変えると、こちらの環境では以下のようになりました。

    ①日本語ファイル名になるケース
     正常ケース。右クリック「対象を保存」のときのみ。
     「対象を保存」は通常は非活性で選択出来ないが、imgタグの前後をAタグで囲うことで活性にすることが出来る。
     正しく保存出来る理由は、Aタグのhrefを見るためであることと、選択した直後に取得しに行くためと思われます。
     リンク先をキャッシュしている場合は、キャッシュから取り出すが、その場合でも正常に保存が可能でした。
     IE7でもIE8共に正しく保存することができる。
     AタグのhrefはURLエンコードされていてもされていなくても両方ともで正しく保存することが出来る。

    ②短いファイル名になるケース
     imgタグのsrcをURLエンコードするか、ブラウザのURL欄で直にURLエンコードした状態で表示したときに、再現可能。
     IE7では、ファイル保存ダイアログに表示されるファイル名はURLエンコードされた状態で出てしまっていたが、
     IE8では、切り詰め~1.JPGという形でファイル保存ダイアログに初期表示されるように変わった。
     保存する際は、①のようにリクエストが飛んだりはしない。

    ③untitled.bmpになるケース(無題.bmpになる人もいる模様)
     imgタグのsrcを日本語のままにするか、ブラウザのURL欄で日本語のURLでリクエストしたときに、再現可能。
     ブラウザのURL欄は日本語だが、裏のHTTPリクエスト自体はURLエンコードしてリクエストされています。
     「Temporary Internet Files」にもindex.datにも存在するが、なぜかそこから取得できない。
     untitled.bmp自体は、メモリ上から持ってきているものかも。(メモリ上ではbmpに伸長する前のデータは破棄されている?)
     IE7でもIE8でも共にuntitled.bmpになってしまう。
     保存する際は、①のようにリクエストが飛んだりはしない。

    【index.datからのひも付け出来ない理由の推測】
    ②では実キャッシュが読めて、③では実キャッシュが読めません。
    ②でも③でも実キャッシュは日本語ファイル名で保存されています。
    ②でも③でもindex.datはutf8でエンコードされていると思っています(未確認)

    以前のウィンドウズスクリプトプログラマさんの言うように
    単純に、index.dat内のkeyのサーチをする際に、日本語で探すかエンコード済みの状態で探すかが異なるためではないでしょうか?
    (なので、②と③の違いが見つからない。index.datと実キャッシュのひも付けは出来ている。)
    で、前回はこの探す文字列を変える方法の案として、「UTF-8で送信する」オプションを削除すれば変わるのではないかという
    話で終わっていましたね。その後どうなりました?
    http://social.technet.microsoft.com/Forums/ja-JP/internetexplorerja/thread/443570b8-8e25-4898-b8ec-83ed219be7a2

    サーバ側で対処可能な案の候補として思いつくのは
     HTTPヘッダのオプションやHTML属性でよいのがないか探す。
     imgで飛ばしてきたURLを一旦リダイレクトしてみる。
    ですかね。


    >【F1100_こまったさん】
    ファイル名は短くなるといっても、拡張子やファイルの中身は正しく保存出来るため、
    ②の方式はuntitled.bmpよりはましかと思われますが、
    IE7とIE8によって、動作が変わるという問題が発生します。

    代案としては、右クリックをさせないようにし、代わりにAタグで飛んだ先をContent-Disposition: attachmentで
    ファイル保存ダイアログを出させ、name属性にてファイル名を表示させる方法があるとも思っています。
    (この方式もブラウザ依存ですが(´・ω・`)

    • 編集済み (´・ω・`) 2009年9月30日 17:25 index.datからのひも付け出来ない理由の推測の追加
    2009年9月30日 16:08
  • 【index.datからのひも付け出来ない理由の推測】
    ②では実キャッシュが読めて、③では実キャッシュが読めません。
    ②でも③でも実キャッシュは日本語ファイル名で保存されています。
    ②でも③でもindex.datはutf8でエンコードされていると思っています(未確認)
    以前のウィンドウズスクリプトプログラマさんの言うように
    単純に、index.dat内のkeyのサーチをする際に、日本語で探すかエンコード済みの状態で探すかが異なるためではないでしょうか?
    (なので、②と③の違いが見つからない)
    で、前回はこの探す文字列を変える方法の案として、「UTF-8で送信する」オプションを削除すれば変わるのではないかという
    話で終わっていましたね。その後どうなりました?
    http://social.technet.microsoft.com/Forums/ja-JP/internetexplorerja/thread/443570b8-8e25-4898-b8ec-83ed219be7a2
    ②はUTF-8でURLエンコードされたURL
    ③はUTF-8でエンコードされたURL
    のようです。
    「UTF-8で送信する」を外しても駄目みたいです。その場合も、
    ③はUTF-8でエンコードされたURL
    のようです。
    2009年9月30日 17:49
  • >F1100_こまったさん
    以下のように右クリックされたタイミングで、URLエンコードさせてしまう方法もあるかもしれません。
    こちらでは、以下の対処でuntitled.bmpだったのを「切り詰め~1.jpg」にすることが出来ました。
    ちらつくのであれば、画像のダブルバッファリングで対処可能かもです。
    IEでのimg要素の読み込み完了イベントはonloadよりonreadystatechange=="complete"をおススメします。

    window.onload = function(){
      document.oncontextmenu = function(){ // ↓img.src.match(/^[^0-9a-zA-Z%]+$/)とかでも
        if(event.srcElement.tagName == "IMG" && !event.srcElement._isEncoded){
          var img = event.srcElement;
          img.src = encodeURI(img.src);
          img._isEncoded = true; //すでにURLエンコード済みであれば、再度は行わない。
        }
      }
    }


    >ウィンドウズスクリプトプログラマさん

    >②はUTF-8でURLエンコードされたURL
    >③はUTF-8でエンコードされたURL
    IE→index.dat→実キャッシュとあったときに、
    index.dat自体に保持しているデータが上記状態だったということでよいですかね。
    IEがindex.dat内のどのレコードかを特定するためのサーチkeyとなる文字列ではなく(実際にそのようなものがあるかは知りませんが)。
    となると③のケースでは実質使えないキャッシュになってしまっているということですね。
    これでは、URLを変えるか、index.datに書き込む時点の動作を変えるかのどちらかしかないですね。。。
    2009年9月30日 18:56
  • ありがとうございます。

    詳細に記載いただき感謝しております。

    また様々な方からも
    ご回答いただきただただ感謝しております。

    こちらで作成するWebアプリでは参考にさせていただきます。

    こちらでASP.NETやタグの記載で制御するページならばよいのですが
    単純にどこかのページでたまたま日本語ファイル名でアップされている画像となると
    もうどうしようもないようですね。

    どこかの設定で対応できるとよいのですが。

    これはもう 仕様 としてあきらめるしかなそうですね。
    2009年10月1日 5:34

  • index.datは、URLで検索すると、キャッシュのディレクトリ番号とファイル名を返すようなデータ構造です。
    index.datをメモ帳で開いて、URLの前半で検索すると、後半がどういうエンコードになっているか見て分かります。

    ③が使えない訳ではないようです。オフラインでキャッシュから読めます。
    IEが読むときには、見つかる。IEが保存するときには、見つからない。
    読むときと保存するときで、IEが使用しているインターフェースが違うとか。
    まさかと思いますが、例えば、~W()はUTF-8で検索して見つかる。~A()はシフトJISで検索して見つからないとか。

    GetUrlCacheEntryInfoW/Aが、そのまさかみたいです。

    2009年10月1日 5:53
  • index.datは、URLで検索すると、キャッシュのディレクトリ番号とファイル名を返すようなデータ構造です。
    index.datをメモ帳で開いて、URLの前半で検索すると、後半がどういうエンコードになっているか見て分かります。
    中身をまともに見てなかったんですが、今回確認しました。
    確かに、index.datファイル内にutf8バイナリで保存されているものと
    utf8をURLエンコードしたものが保存されていることを確認しました。


    GetUrlCacheEntryInfoW/Aが、そのまさかみたいです。


    おお、すばらしいですね!
    おかげでデバッグ版wininet.dllの存在を思い出しました。このdllはAPIの呼び出し履歴をファイルとして吐いてくれます。
    そこで色々確認してみました(IE7ですが。IE8対応のデバッグ版wininet.dllはまだ見当たらないので)

    ●●APIについて●●
    キャッシュを保存したい時が
    SetUrlCacheEntryInfoで
    普通にブラウザのキャッシュを探したいときが
    GetUrlCacheEntryInfoで
    名前を付けてファイルを保存のときは
    RetrieveUrlCacheEntryFile
    ではないかと思いました。
    (どちらもINTERNET_CACHE_ENTRY_INFO構造体を得る為のAPIのようですが。。)


    ●●デバッグログがどのように出力されたかの概略●●
    【<img src="あ.jpg">】が書かれたHTMLファイルを表示するケース

    ファイル名がutf8状態でSetUrlCacheEntryInfoAの第1引数に渡される(index.datと同様)
      SetUrlCacheEntryInfoA("http://hogehoge/あ.jpg", 0x4edec60, 4608)
                         ↑上記の「あ」の部分は実際はutf8です。

    上記状態で右クリック「名前を付けてファイルを保存」とすると
    ファイル名がshift-jis状態でRetrieveUrlCacheEntryFileAの第1引数に渡されていました。
      RetrieveUrlCacheEntryFileA("http://hogehoge/あ.jpg", 0x4557bc8, 0x45579b0, 0x0)
        RetrieveUrlCacheEntryFileA() returning 2 [ERROR_FILE_NOT_FOUND]
      RetrieveUrlCacheEntryFileA() returning FALSE

    結果、ファイル保存ダイアログのファイル名はuntitled.bmpになりました。


    【<img src="%E3%81%82.jpg">】が書かれたhtmlファイルを表示するケース
    すでにキャッシュにあるせいか、画面を出してもSetUrlCacheEntryInfoは呼び出されず。

    上記状態で、「名前を付けてファイルを保存」した場合
      RetrieveUrlCacheEntryFileA("http://hogehoge/%E3%81%82.jpg", 0x4557bc8, 0x45579b0, 0x0)
      RetrieveUrlCacheEntryFileA() returning TRUE

    →結果、ファイル保存ダイアログのファイル名は%E3%81%82.jpgになる(IE7なので)


    ●●対応案?●●
    ログを眺める限り、IEの内部的にはHttpOpenRequestWに渡す文字列次第で
    SetUrlCacheEntryInfoAへ渡す文字列が決まる(index.datへの内容が決まる)ように見えました。
    おそらく、IE的にはこの動きは外せないんじゃないかと思いました。
    (エンコードされているかどうかでキャッシュを分ける為にです。なぜ分ける必要があるかは分かっていませんが。)
    で、右クリックでファイルへ保存のみの動作がおかしいことを考えると、そのタイミングで呼び出すAPIを
    RetrieveUrlCacheEntryFileA→RetrieveUrlCacheEntryFileWへ変更するだけで、
    対応可能なのではと思えてきました(むしろHttpOpenRequestWと連動するようになればよい?)。
    この実現をサーバ側で制御出来ればよいのですが。。。

    2009年10月1日 18:12
  • すばらしい。長い間の謎がやっと解けましたね。

    あとは、MSがIEを~A→~Wに修正するのと、~Aのドキュメントを修正するだけかな。
    2009年10月2日 6:39
  • こんにちは、フォーラムオペレーターの三沢健二です。

    みなさん、いつも有益な情報・アドバイスいただき、誠にありがとうございます (^^)

    こちらのスレッドは同じような情報をお探しの方に、大変参考になるのではないかと思いましたので、[回答としてマーク] のチェックを付けさせていただきました。

    それでは、また何かありましたら、ぜひ TechNet フォーラムをご利用ください!
    今後ともよろしくお願いします。

    ______________________________________
    マイクロソフト株式会社 フォーラム オペレーター 三沢健二

    2009年10月22日 6:01
    モデレータ
  • 現象を確認したい方はこちら。
    http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:%E5%AE%87%E9%83%BD%E5%AE%AE%E9%A4%83%E5%AD%90%E5%83%8F.jpg
    右クリック「名前を付けて画像を保存」 → 短いファイル名 ⇒ 日本語ファイル名
    右クリック「対象を保存」 → 日本語ファイル名 ⇒ 同
    クリックして画像だけを表示、「名前を付けて保存」 → 短いファイル名 ⇒ 日本語ファイル名

    さらに質問者の現象を確認したい方はこちら。
    ttp://upload.wikimedia.org/wikipedia/ja/7/73/宇都宮餃子像.jpg
    「名前を付けて保存」 → untitled.bmp ⇒ 日本語ファイル名

    ie11では、
    ieの履歴の日本語文字化けが直った! - マイクロソフト コミュニティ
    ので、こちらも直ったか確認してみたら、上記と状況がだいぶ違います。直ったってことかもしれません。 ie11

    IEの日本語ユーザ名サポート状況 - マイクロソフト コミュニティ
    で書いたようにANSI版関数に使用をやめたのかも。
    2013年12月28日 13:38