ヒマをみつけてWeb開発
その場の思い付きを、ヒマをみつけてWebサイトにしてみるブログ

CGIのURLエンコードと、JavascriptのURLエンコードは微妙に違う

Wednesday, 22 July 2009 07:48 by sabro

クリエモンでURLエンコード周りのバグを出してしまいました( ̄□  ̄ ||

原因はCGIとJavascriptでURLエンコードが微妙に違うことでした。WikipediaのURLエンコードのページをみると、Javascriptでは、スペースは「%20」にエンコードされるが、CGI側では普通は「+」に変換されると書いてあります。なんでそんなややこしいことになってんだろ。これって知らないの僕だけで他のWeb開発者の間では常識なのかな(_ _ ||

とりあえず、おかしくなっていた部分では、HttpUtilityクラスのUrlEncodeメソッドが使われていました。以下はPowerShellでちょっと確認してみたところ。HttpUtilityクラスは、そのままでは参照できないんでリフレクションで「System.Web.dll」を読み込んでいます。


PS C:> [System.Reflection.Assembly]::LoadWithPartialName("System.Web")

GAC    Version        Location
---    -------        --------
True   v2.0.50727     C:\Windows\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll

PS C:> [System.Web.HttpUtility]::UrlEncode("<hoge fuga>")
%3choge+fuga%3e


PowerShell覚えると、インタプリタで動作確認ができちゃって楽ちんだな~( ̄∇ ̄) で、結果を見ると確かに「+」にエンコードされていますね。

調べてみると、UriクラスのEscapeDataStringメソッドを使えばJavascript形式のエンコードが出来るらしいとのこと。どれどれ


PS C:> [Uri]::EscapeDataString("<hoge fuga>")
%3Choge%20fuga%3E


おお、たしかに「%20」にエンコードされました(^^) 結局、UrlEncodeメソッドを使用している箇所を、のきなみEscapeDataStringメソッドに置き換えて、問題は解決したのでした。

ちなみに、UriクラスにはEscapeUriStringというメソッドもあります。こちらがどんな動作をするのか気になったので、サクッと確認してみました。


PS C:> [Uri]::EscapeDataString("http://www.hogefuga.com/<hoge fuga>")
http%3A%2F%2Fwww.hogefuga.com%2F%3Choge%20fuga%3E

PS C:> [Uri]::EscapeUriString("http://www.hogefuga.com/<hoge fuga>")
http://www.hogefuga.com/%3Choge%20fuga%3E


EscapeDataStringメソッドは、URLのコロンやスラッシュもエンコードしてしまいますが、EscapeUriStringメソッドは、URLを構成するための記号はエンコードしていません。すでに、URLになっている文字列に対してエンコードしたい時はこちらを使えばいいわけですね( ̄∇  ̄ )

Tags:   , , ,
Categories:   .NET
Actions:   Permalink | Comments (48) | Comment RSSRSS comment feed

PowerShellでWeb上のZipファイルをダウンロードして解凍する

Monday, 22 June 2009 09:45 by sabro

ちょっと、とあるWebサーバ上にあるZipファイルを定期的にダウンロードして解凍する必要が出てきたんで、適当な言語でスクリプト作ることにしました。ただ、要件としてWindows上で動作する必要があって、せっかくなんで、前から気になってたPowerShellでやってみることにしました。

# Zipファイル操作用のライブラリをロード
[System.Reflection.Assembly]::LoadFile('C:\temp\ICSharpCode.SharpZipLib.dll')

# WebClientクラスのインスタンスを作成
$wc = New-Object System.Net.WebClient

# Zipファイルをダウンロード
$wc.DownloadFile("http://www.hoge.com/fuga.zip","C:\temp\temp.zip") 

# Zipファイルを解凍
$zip = New-Object ICSharpCode.SharpZipLib.Zip.FastZip
$zip.ExtractZip("C:\temp\temp.zip", "C:\temp\" + [DateTime]::Now.ToString("yyyyMMdd"), "")



Zipファイルを解凍する方法は、COMを通してエクスプローラの機能を使うとか、コマンドラインで解凍ソフトを呼び出すとか色々あるみたいだけど、今回は、ICSharpCode.SharpZipLib.dllを使ってみました。PowerShell上で、外部アセンブリのクラスを使用したい場合は、リフレクションを使ってアセンブリをロードしておく必要があるみたいなので最初にロードしてます。[System.Reflection.Assembly]::LoadFileみたいな呼び方してるけど、静的なメンバを呼び出す時はこうしないといけないらしいです。

次にWebClientのインスタンス化、New-Objectコマンドでインスタンス作成です。そのインスタンスのDownloadFileメソッドを使用して、ファイルを同期的に取得しています。

最後に、ICSharpCode.SharpZipLib.dllのFastZipクラスを使用して解凍。解凍したファイルは、日付ごとのフォルダに格納してます。

とまあ、こんな感じで結構簡単にできました( ̄∇ ̄)でも、いざ実行してみるとエラーが・・・( ̄□  ̄ ||  どうやら、PowerShellではデフォルトの実行ポリシーが「Restricted」になっていて全てのスクリプトの実行が禁止されているとのこと。実行ポリシーは他に「AllSigned、RemoteSigned、Unrestricted」があるそうですが、今回はインターネット上のスクリプトのみ署名を求める「RemoteSigned」にポリシー変更してみました。

Set-ExecutionPolicy RemoteSigned


これをPowerShellのプロンプト上で実行してやれば動くようになりました(^^)

Tags:  
Categories:   .NET
Actions:   Permalink | Comments (46) | Comment RSSRSS comment feed