ホーム ブログ ページ 49

jQuery グラフ表示 〜Google Charts〜

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rickNo23です。
今回はjQueryのプラグインGoogleChartsを使って簡単にグラフを表示する方法を紹介します。

環境

jquery1.4.2
jgcharts.js.0.9.7

Download

本家

ソース

< script type=”text/javascript” src=”http://search.kbmj.com/javascripts/jquery-1.4.2.min.js”   >< /script >
< script tyep=”text/javascript” src=”http://rikiya.sakura.ne.jp/jQuery/jgcharts/jgcharts.js” >< /script >

< script language=”JavaScript” >< !–
  jQuery(function(){
    var api = new jGCharts.Api();
    jQuery(‘< img >’).attr(‘src’, api.make({data : [[153, 60, 52], [113, 70, 60], [120, 80, 40]]})).appendTo(“#bar1”);
  })
//– >< /script >
< div id=”bar1″ >< /div >

解説

まずはjqueryの読み込みでjquery-1.4.2.min.jsを参照
次にGoogleChartsの読み込みでjgcharts.jsを参照
var api = new jGCharts.Api();
で初期化
jQuery(‘< img >’).attr(‘src’, api.make({data : [[153, 60, 52], [113, 70, 60], [120, 80, 40]]})).appendTo(“#bar1”);
でデータを送信して画像を取得し、divのbar1へ出力しています。

オプション

本家を見てもらうと分かる通りグラフには様々な種類があります。
api.makeの中で
type : ??
とすることで別の種類のグラフに変わります。
例えばtype : ‘bhs’などにすると帯グラフに変化します。
また、画像サイズには制限がかけられておりmaximum size 300,000 pixelsとなっています。
サイズの変更は
size : ‘??x??’
で変更できます。
他にも様々なオプションがありますので、興味があったら本家を見てみてください。

apache の脆弱性

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

先日、apacheの脆弱性が公開された。この脆弱性は、既存の全バージョンで確認され、「緊急」扱いとなっている。

今回は、この脆弱性が如何に危険な存在であるか、検証してみよう。

今回見つかった脆弱性は、と呼ばれるもので、ざっくりと言ってしまえば、サービス拒否攻撃の類だ。サービス拒否攻撃には、いくつかの手法があり、

  1. 帯域圧迫型
  2. socket飽和型
  3. CPU占有型
  4. メモリ圧迫型

の4種類に大別することが出来る。このうち、1は一般的にはDDoS攻撃と呼ばれるもので、古くは「田代砲」と呼ばれる攻撃ツールもあった。2は、1と似ているが、大した帯域を使わず、大量にセッションを張るだけ張り、持続させて、相手のsocketを食いつぶす。syn floodやack flood攻撃もこの種になる。

3は、CGIを呼び出す部分のみを、高速に外部から呼び出し、CGIに費やす負荷を極限まで上げる方法だ。4は、ファイル転送を行う際に、大量かつ大容量のデータを転送することで、内部メモリを飽和させる方法だ。

今回見つかった脆弱性は、3と4を合わせ持つ強力なものだ。通常3や4を実行する場合、攻撃側もそれ相応の機材やネットワークを必要とし、botネットを用いることが一般的だ。しかし、今回の脆弱性を検証するために用いられたツールは、わずか8000バイト弱のデータを、1つのhttpリクエストにしたため、接続しているだけだ。

通信内容は、次のようになっている

HEAD / HTTP/1.1

Host: 192.168.2.113

Range:bytes=0-,5-0,5-1,5-2,5-3,5-4,5-5,5-6,5-7,5-8,5-9,5-10,5-11,5-12,5-13,5-14,5-15,5-16,5-17,5-18,5-19,5-20,5-21,5-22,5-23,5-24,5-25,5-26,5-27,5-28,5-29,5-30,5-31,5-32,5-33,5-34,5-35,5-36,5-37,5-38,5-39,5-40,5-41,5-42,5-43,5-44,5-45,5-46,5-47,5-48,5-49,5-50,5-51,5-52,5-53,5-54,5-55,5-56,5-57,5-58,5-59,5-60,5-61,5-62,5-63,5-64,5-65,5-66,5-67,5-68,5-69,5-70,5-71,5-72,5-73,5-74,5-75,5-76,5-77,5-78,5-79,5-80,5-81,5-82,5-83,5-84,5-85,5-86,5-87,5-88,5-89,5-90,5-91,5-92,5-93,5-94,5-95,5-96,5-97,5-98,5-99,5-100,5-101,5-102,5-103,5-104,5-105,5-106,5-107,5-108,5-109,5-110,5-111,5-112,5-113,5-114,5-115,5-116,5-117,5-118,5-119,5-120,5-121,5-122,5-123,5-124,5-125,5-126,5-127,5-128,5-129,5-130,5-131,5-132,5-133,5-134,5-135,5-136,5-137,5-138,5-139,5-140,5-141,5-142,5-143,5-144,5-145,5-146,5-147,5-148,5-149,5-150,5-151,5-152,5-153,5-154,5-155,5-156,5-157,5-158,5-159,5-160,5-161,5-162,5-163,5-164,5-165,5-166,5-167,5-168,5-169,5-170,5-171,5-172 以下略

こう言った攻撃コードを、1回の通信で行っている。

ここで注目すべきは、「Range:bytes=」だ。

このRangeは、データを分割する際に用いる方法

だ。つまり、大量のデータがある場合、そのデータをいくつかに分割し、転送することを要求している。5-6 5-7 と言ったように、特定のバイトからバイトまでを分割して転送要求を行う。5-0 バイトから5-1299バイトまでを、1バイトづつ増やしながら、同じものを含め、再度転送することを要求する。この要求を受けたターゲットは、その要求に従い、律儀に転送しようと試みる。

これを受け取ったサーバは、下記に示すように、要求された分だけ、apacheの接続を受け止めようとする。

見てわかるように、この時点でload average は、40を越えている。通常のサーバではありえない現象だ。

この時の通信ログは

192.168.3.26 – – [01/Sep/2011:10:20:37 +0900] “HEAD / HTTP/1.1” 206 354 “-” “-“

192.168.3.26 – – [01/Sep/2011:10:20:37 +0900] “HEAD / HTTP/1.1” 206 354 “-” “-“

192.168.3.26 – – [01/Sep/2011:10:20:37 +0900] “HEAD / HTTP/1.1” 206 354 “-” “-“

192.168.3.26 – – [01/Sep/2011:10:20:37 +0900] “HEAD / HTTP/1.1” 206 354 “-” “-“

192.168.3.26 – – [01/Sep/2011:10:20:37 +0900] “HEAD / HTTP/1.1” 206 354 “-” “-“

192.168.3.26 – – [01/Sep/2011:10:20:37 +0900] “HEAD / HTTP/1.1” 206 354 “-” “-“

192.168.3.26 – – [01/Sep/2011:10:20:37 +0900] “HEAD / HTTP/1.1” 206 354 “-” “-“

192.168.3.26 – – [01/Sep/2011:10:20:37 +0900] “HEAD / HTTP/1.1” 206 354 “-” “-“

192.168.3.26 – – [01/Sep/2011:10:20:37 +0900] “HEAD / HTTP/1.1” 206 354 “-” “-“

となっており、先程の様な、Range:bytes=は含まれていない。

この状況が続くとどうなるのか、状況を見てみよう。

waが97%を示していることがわかるだろうか。これは、IO Wait と呼ばれるもので、通信ではなくIO系の処理にそれだけのwaitが発生していることを示す。

この数値が大きければ、大きいほどシステムの反応速度は落ち、ファイルの書き込みや様々な応答速度は悪くなる。

webブラウザで接続した際、クルクルとレインボウカーソルが発生し、何時まで経っても、画面が表示されない。そういった状況を想い出せばよいだろう。

この状況が続くと、メモリもCPUも圧迫され続け、システムそのものへのssh接続もままならなくなる。

こうなると、システムは次の画面にあるように、OOM Killer を発動する。

この状況では、諸悪の根源を、apache に有ると考え、apache のタスクを殺しにかかる。

この時、apacheの抱えるタスクは当然のごとく消され、最悪の場合システムが完全にロックする場合もある。

この記事を書いてる現在、既にapache 2.2.20のパッチが提供され、それ以外のバージョンでも暫定的な対応策が公開されている。まだ、apacheの対策を行っていないのであれば、早急な対応されることの望む。最悪の場合、apacheどころか、OSまで止まるのだから。

この後の検証で、killapache.pl のHEADをGETに書き換えた場合、HEADの時より、高速にサービス拒否攻撃が成立し、OOMKillerが発動する事がわかった。

これは、HEAD によって呼び出される情報が、Serverの情報のみに集約され、あまり、1300バイトを超えることが無いことに対し、GET の場合は、HTMLが含まれ、容易に1300バイトを超えるためと推測される。

DeNAの障害

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

8月25日、DeNAが提供するモバゲーが9時30分くらいからアクセスできなくなった。折しも、Apacheで、重大なセキュリティホールが報道された為、落とされた?と、思っていたら・・・

どうやら、Apache の脆弱性によるものではなく、単なるデータセンタの障害だったらしい。

DeNAが入るデータセンタの発表によると

弊社データセンターにおける通信障害について

本日9時30分頃、弊社データセンターにおいて通信障害が発生いたしました。この障害は、データセンター内のテナント様が行なっていた工事中に誤って回線を切断したことによるものです。

とのことで、第三者の人為的ミスによる障害と判明した。

今回の、通信障害から分かることを考えてみたいと思う。

  1. データセンタは、共用ビルだった?
  2. ネットワークが共有部分を走っていた?
  3. ネットワークがシングルポイントになっていた?

まず、1の問題から。様々な理由からデータセンタのみを運用するデータセンタの構築は難しいとされる。だが、データセンタを構成する上で重要となる、クリティカルな情報を扱う場合、L7もしくはL6程度のファシリティが必要になると考えている。つまり、DeNAが入るデータセンタは、クリティカルデータを扱う事はできないと、宣言しているようなものだ。

次に、2の問題。共有ビルの場合、通信ケーブルを専有部分のみに走らせることは厳しい。しかしながら、他のデータセンタでは、共有部分に於いても、通信ケーブルを切断されないように、シールド線を用いたり、囲いを使ったりして対策を施している。

最後に、3の問題。データセンタを設計する上で、一番重要な問題は、シングルポイントを絶対に作らないこと。これは、電源ケーブルしかり、通信ケーブルしかり、2重3重に経路設計を行い、物理線は当然のこと、複数の異なるライン、複数の異なる物理経路を用い、仮に1本切断されたとしても、他の経路で確実に到達するように設計を行う。

DeNAが入っていたデータセンタは、耐震性を謳っているようだが、地震云々よりも、こういったアタリマエのことをやってから、耐震性を考えて欲しいものである。

侵入者と付き合う方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

侵入者に対する考え方は、様々なポリシーによって、多種多様に存在する。

今回は、様々なポリシーの中から、少し変わった対策を紹介しよう。

まず、侵入者に対する考え方は、大きく分けて次のように分類される

  1. 絶対防御
  2. ノーガード戦法
  3. ハニーポット

このうち、多くの企業や組織が行っているのが、絶対防御の考えである。通常であれば、侵入者の試みを快く思わず、様々なポイントで、侵入者の試みを排除しようとする。

一切の試みを禁止しているため、最悪の場合DDoSを使って、サイトそのものを外部から閲覧させないように攻撃される場合がある。

次に、割と多く困った存在が、ノーガード戦法だ。普段は何もせず、最低限の対策だけ行い、なにか問題が発生したら、ひたすら謝る方法だ。先程の、絶対防御に比べ、多くのリソースを必要としないため、月々のコストを下げることが出来る。もちろん、実際の攻撃を受けた場合、多大な損害が発生するわけだが、万一の事態に備える必要がないため、状況によっては、ノーガード戦法が、コストが安くつくかもしれない

最後に、ハニーポット。通常のサイトのフリをし、脆弱なサイトの様に見せかけて、攻撃者の動向を調べる手法だ。一般的な企業がこれを採用する事は少なく、どちらかと言えばセキュリティを生業とする企業が用いる。

今回紹介する手法は、3つのどのモデルにも該当しない。

多くの侵入者は、ちょっとした遊びゴコロで侵入している事が多い。たしかに、プロの犯罪者が情報を盗むために侵入するケースもあるが、それはごくごく一部だ。

侵入者は、まず、脆弱なパスワードを設定したアカウントを探し出し、そのアカウントに対してsshやtelnet ftpなどに対して攻撃を仕掛ける。ここで、脆弱性なアカウントとパスワード(例えば id:test passwd:test 等の様に)を見つけ出し、サイトに侵入したとする。

次に侵入者は、いつでもそのサイトに侵入できるようにバックドアを仕掛ける。そして、ローカルexploitを用い、管理者権限を奪い、rootkit を仕掛け・・・と、こんな具合に侵入して、次に踏める場所を調べ始める。これと同時に、有用な情報がサイト内に無いかを調査することも忘れない。ここまで書くと、ハニーポットに視えるだろう。たしかに、このままではハニーポットだ。有益な情報をわざと散りばめ、かつ、それに毒入れを行っていたらどうなるだろうか。

通常のテキストファイルだけでは、毒入れすることは難しいが、PDFファイルや、GIFファイルなどであれば、毒入れすることはかなり容易くなる。具体的な毒入れ手法は書かないが、毒入れされた有益な情報を侵入者が持ち帰り、自分のPCや友だちのPCでひらこうものなら、それを開いたPCの情報が、丸裸のように、別サイトに通知されるように仕込んでおく。つまり、有益な情報を盗んだ!と思ったら、実際には攻撃者が丸裸にされるわけだ。

侵入者には、簡単に入れるという快楽を与え、実際には侵入者の個人情報を盗む。そういった対策を考えてみるのも一考だろう。

夜フクロウの短縮URLでマカフィーのサービスを使ってみる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Twitterが自動的に付加する短縮URLはセキュリティとか考えてるかよくわからないので安心できそうなサービスを使ってみます。

(先に結論を言うと、無駄足でした。)

なにやら最近、TwitterでURLを普通に流すと勝手にt.coという短縮URLに変更してしまいます。

短縮URLは少ない文字で記述するには非常に便利ですが、セキュリティ上考えられているかというとよくわかりません。

短縮URLでセッションを奪ったりなんていうのは昔からよくあった話で今更感がありますが、このようにデフォルトサービスにまで発展するとさすがにまともなサービスを検討して使っておかないとまずいターンだろうと思います。

で、まともなサービスがないかなーと思っていたら、同僚から「マカフィーの短縮URLがあるよ」と教えてもらいました。

調べてみると、「McAf.ee」というサービスで、マカフィーのデータベースを使ってURLを評価しているようです。(参考記事: McAfee、サイトの安全性も評価するURL短縮サービス「McAf.ee」ベータ版公開)

これなら安心して使えそうということで、さっそく夜フクロウで使えるようにしてみました。

夜フクロウの環境設定画面を開きます。

そして、詳細タブのURL短縮サービスの項目でカスタムを選択します。

次に、ダイアログが現れるので、以下のように入力します。

http://mcaf.ee/api/shorten?input_url=%@&format=text

フォーマットはテキストのままにしておきます。

これで短縮URLで「McAf.ee」が使えるようになりました。

ですが….結局、この短縮URLにしても、Twitter側が勝手にt.coという短縮URLに変更してしまいます。

対策としては、Command+Sで短縮URLに変更したあとに、http://からhを削ってみるとよいでしょう。

McAf.eeのAPIのドキュメントはThe McAf.ee APIにあります。自分のサービスに組み込みたい人は、ぜひ参照してください。

Rails3.1 + SCSS で幸福実現してみる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Rails3.1ではSCSSが標準で搭載されました。とても面白い仕組みなので紹介します。

CSSはWebページにおいて構造とデザインを分離するとても重要な仕組みです。しかし、デザインが複雑になるに連れてどんどん肥大化していき、うまくコントロールしないとメンテナンスが容易ではなくなってしまいます。よく、新しいデザインを追加したと思ったら他のデザインとぶつかってしまったなんてことがあったり、一箇所にクラスの定義がなくバラバラになっていて途方にくれてしまうなんてことはよくあります。

SCSSはこのような悩みをほどよく解決してくれるシンタックスを持つCSS用のメタ言語で、Rails 3.1から採用されました。SCSSについての詳細は、Sass、そしてSassy CSS (SCSS) をご覧ください。

今回は、黒田努氏のはじめる!Rails3(達人出版)のサンプルプログラム:hinagikuで、7.3 スタイルシートの作成に登場するサンプル(public/stylesheets/tasks.css)を例に、Rails 3.1でSCSSで記述した場合にどのような動きをするのかを紹介します。

書籍のサンプルでは、以下のようなコードになっています。

table.tasks {
  width: 560px;
  margin: 5px auto;
  background-color: #eee;
  border-collapse: collapse;
  border-spacing: 0;
}

table.tasks tr {
  border: solid 1px #ccc;
}

table.tasks td {
  padding: 5px;
}

table.tasks col.name {
  width: 320px;
}

table.tasks col.due_date {
  background-color: #ddd;
}

これをSCSSで書きなおしてみます。

まず、書籍と同様にコントローラを作成します。

$ rails generate controller tasks
      create  app/controllers/tasks_controller.rb
      invoke  erb
      create    app/views/tasks
      invoke  test_unit
      create    test/functional/tasks_controller_test.rb
      invoke  helper
      create    app/helpers/tasks_helper.rb
      invoke    test_unit
      create      test/unit/helpers/tasks_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/tasks.js.coffee
      invoke    scss
      create      app/assets/stylesheets/tasks.css.scss

この時に、app/assets/stylesheets/tasks.css.scssも作成されます。

先ほどのCSSをapp/assets/stylesheets/tasks.css.scssに記述します。SCSSでは以下のようになります。

// Place all the styles related to the tasks controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

table.tasks {
    width: 560px;
    margin: 5px auto;
    background-color: #eee;
    border-collapse: collapse;
    border-spacing: 0;

    tr {
        border: solid 1px #ccc;
    }

    td {
        padding: 5px;
    }

    col.name {
        width: 320px;
    }

    col.due_date {
        background-color: #ddd;
    }
}

このようにCSSで書きづらかった階層関係が非常にわかりやすく書くことができます。個人的に困っていたデザイナさんが作ってくれた新しいデザインを忙しいとかいう理由で一番下に追加して阿鼻叫喚とかいうことが、この階層化によって発生しづらくなっています。

さて、今まではCSSの指定は <%= stylesheet_link_tag :all %> として、public/stylesheets 以下のものを全て読み込む形になっていましたが、Rails 3.1からは、 <%= stylesheet_link_tag “application” %> となり application.css のみ標準で読み込む形になります。ということは、tasks.css はどこにいくのでしょうか?正解は、SCSSを利用してtasks.css.scssの内容が application.css に入るのです。

実際にこの仕組みをみてみましょう。

先ほど作成したコントローラにアクセスしてみます。

Started GET "/tasks" for 127.0.0.1 at 2011-08-09 14:10:51 +0900
  Processing by TasksController#index as HTML
MONGODB hinagiku_development['tasks'].find({:done=>false})
Rendered tasks/index.html.erb within layouts/application (616.2ms)
Completed 200 OK in 678ms (Views: 677.1ms)


Started GET "/assets/application.css" for 127.0.0.1 at 2011-08-09 14:10:52 +0900
Compiled ~/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss  (45ms)  (pid 85886)
Compiled ~/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/application.css  (1ms)  (pid 85886)
Compiled ~/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/application.css  (0ms)  (pid 85886)
Served asset /application.css - 304 Not Modified (96ms)


Started GET "/assets/application.js" for 127.0.0.1 at 2011-08-09 14:10:52 +0900
Served asset /application.js - 304 Not Modified (19ms)

ここで、Compiledという文字があるとおり、コンパイルをしているということになります。

実際に出力されるCSSは以下のようになります。

/*
 * This is a manifest file that'll automatically include all the stylesheets available in this directory
 * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
 * the top of the compiled file, but it's generally better to create a new file per style scope.
*/
/* line 5, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks {
  width: 560px;
  margin: 5px auto;
  background-color: #eee;
  border-collapse: collapse;
  border-spacing: 0;
}
/* line 12, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks tr {
  border: solid 1px #ccc;
}
/* line 16, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks td {
  padding: 5px;
}
/* line 20, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks col.name {
  width: 320px;
}
/* line 24, /Users/btm/develop/ruby/mongo_rails3_test/hinagiku/app/assets/stylesheets/tasks.css.scss */
table.tasks col.due_date {
  background-color: #ddd;
}
// Place all the styles related to the tasks controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

出力されたファイルはほとんど元の変換前と同じ内容になりました。すばらしい!

さて、今回 /assets/stylesheets にアクセスしているのに気をつけてください。以前では /stylesheets にアクセスしていたものが変わっています。これは、assetという仕組みを利用しているためで、config/application.rbから変更ができます。

    # Enable the asset pipeline
    config.assets.enabled = false

falseになっている場合は、以前と同様に public/stylesheets 以下を見に行くようになります。

SCSSは非常に面白い仕組みです。まさに幸福実現です。Sass、そしてSassy CSS (SCSS)には非常に多くの例があります。ぜひ、ご一読の上、Rails 3.1+SCSSの世界に飛び込んで下さい。

ちなみに、筆者はCoffeeScriptよく知らないので、そっちの方は別の人が記事にしてくれると期待しています。

tsocksをつかったリポジトリアクセス

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

社内用の開発の為、ノートPCで自宅⇔会社で同じリポジトリを使いたいという要望がわりと多くあると思いますが、そんな時に便利なソフトウェアを紹介します。まず、以下の図をみてください

  上記のイメージにある通り、社内にいる人間はそのままリポジトリへアクセスできますが、その人がノートPCをもって自宅へ帰り、チェックアウトしようとしてもできません。

  もし社内にsshログインできるようなゲートウェイサーバがあるのであれば、そのサーバを使ってポートフォワードをしてチェックアウトすればひとまず目的は達成できそうです。 でも、なんか不便だと思います。やり方は様々かと思いますが、社内では


% svn co http://repo.example.co.jp/prjname/ 

とするだけで事足りたのに、ポートフォワードを使って外出先からチェックアウトする時は


% svn co http://localhost:8080/prjname/

みたいな事をしなくてはならず、スマートじゃない気がします。そもそもリポジトリのURLを同等に扱いたいです。 これをtsocksというコマンドで解決したいと思います。MacユーザはMacPortsから導入するのが楽です。


% sudo port install tsocks

設定ファイルを準備します。以下のような感じで。


% cat /opt/local/etc/tsocks.conf 
server = 127.0.0.1
server_port = 1080
tordns_enable = false
server_type = 5

この状態でゲートウェイサーバへログインをして、セッションを貼るようにしてみます。


% ssh -D 1080 ゲートウェイサーバ

上記セッションを活かした状態で、社内ネットワークの「外」からアクセスしてみます。 社内にいるときにチェックアウトしたコマンドの先頭に”tsocks”をつけるだけでsocks経由でのアクセスにすることができます。


% tsocks svn co http://repo.example.com/prjname/

あとはソースコードにバンバンコミットです。社内では


% svn ci -m "test commit" filename

などとして普段通りアクセスしていればよいですし、外出先などでは


% tsocks  svn ci -m "test commit" filename

のように、tsocksをつければいいだけです。 subversionを例に使いましたが、gitでも同じ事です。 これだったらあまり難しい事を考えず、どこでも同じURLをつかってリポジトリにアクセスできるので、便利じゃないかと思います。

2011年 夏の推薦図書:コードコンプリート第二版

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


こんにちは、SHIMADAです。

今回は、いつもと少し違った趣向ですが、推薦図書の紹介をしたいと思います。CODE COMPLETE 第二版

コードコンプリート CODE COMPLETE 第二版(上巻・下巻)
日経BPソフトプレス刊
Steve McConnell(スティーブ・マコネル)著

 
この本にはかなり思い入れがあります。
というのも、IT業界で飯を食おうと決心したときに、最初に大枚をはたいて買った本だったからです。そのときはまだ初版でした。
情報系の専門教育を受けていない自分が、これまでまがりなりにもやってこれたのは、この本のおかげだと思います。

このエントリで言いたいこと

上下巻に分かれていて、それぞれ六千円超という値段なので、買うとしたらかなり躊躇してしまうかも知れません。
 

でも、買え!

 
それだけの価値があります。
もしかしたら既に職場にある、あるいは申請したら買ってくれる、といった恵まれた環境にいらっしゃる方もおられるかも知れません。
どんなことが書いてあるのか、事前に確かめられる幸運に感謝しましょう。
 

でも、買え!

 
図書館で本を借りたときよく体験するのですが、娯楽のための小説や雑誌とちがって、こういう歯ごたえのある本は自分の懐を痛めて買わないと、人間なかなか読まないものです。
大丈夫。一万三千円、充分モトが取れる本です。自分に投資しましょう。

どんな本なのか?

三行でおk、という声が聞こえてきたので三行でまとめると、

  • ソフトウェアコンストラクションに関する
  • 特定の言語や方法論に限定されない
  • 普遍的なベストプラクティス

を広い範囲で収集し、体系的にまとめた本です
プログラマ、エンジニアとして、最低限知っておかなければいけない、でも入門書や教科書にはあまり載っていない現場寄りの知識を具体的に教えてくれます。
知っていればしなくていい苦労、というものがあります。システムの開発に携わるにあたって、しなくていい苦労を避けたい人に読んで欲しい本です。
またそういう種類の苦労は、えてして他の人を巻き込みます。いらぬ苦労に巻き込まれたくない人にもおすすめです。

「ソフトウェアコンストラクション」ってなに?

「ソフトウェアコンストラクション」というのは耳慣れない言葉かもしれません。
システム開発における各種アクティビティの一部で、下図のグレーで塗られた楕円の部分になります。(文字の大きさが、本書における取扱いのウェイトを示しています。)
「コーディングとデバッグ」が最も大きなウェイトを占めていて、「課題定義」「要求開発」「システムテスト」などは範囲外となっています。


本書 p.6 図1-2 を引用

ただし、この本で触れていないアクティビティが、システム開発にとって重要でないということはないです。
そういった方面については他に有用な書籍が充実しているので、あえて焦点を当てていないという側面があります。

内容についてもっと詳しく知りたい

@ITさんのサイトで上下巻の完全な目次と、一部の章の本文が公開されています。

@IT: BOOK Preview:Code Complete 第2版

  • 第6章 クラスの作成(前半)
  • 第6章 クラスの作成(後半)
  • 第24章 リファクタリング
  • 第34章 ソフトウェア職人気質とは


本書を買うつもりがない人も、上記ページは無料で公開されてますので、是非読んでみて下さい。

最後に本文からの引用を

第一部「基礎を固める」から、本書の姿勢をよく表している一節を引用してみます。

言語の「中で」のプログラミングと言語の「中へ」のプログラミングの違いを理解することは、本書の内容を理解する上で重要である。
重要なプログラミング原理のほとんどは、言語の種類ではなく、言語を使用する方法に依存する。使用したい構造が言語に含まれていない、あるいは何らかの問題が起きやすいという場合は、それらを補正できないかどうか試してみよう。コーディング規約、標準、クラスライブラリなどの補強を独自に考案してみよう。

(上巻 p.83 4.3.1 「言語の『中へ』のプログラミングの例」より)

追記:弊社社員へ

本書を使った読書会/勉強会について検討しています。(どういう形で進めるのがいいか、頭を痛めています)
興味のある人は是非SHIMADAまで一声掛けて下さい!

64bit版OSへのインストール

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

前回、PHPのソースインストールで32bit版CentOSへのインストール方法を記載しましたが、最近64bit版CentOSにインストールする機会があったので、PHP以外も含め変更点をメモしておきます。

●PHPのインストール

下記のエラーが出るので、オプションに「–with-libdir=lib64」を追加する。

configure: error: mysql configure failed. Please check config.log for more information.
# ./configure –with-apxs2 –with-bz2 –enable-calendar –with-curl –enable-exif –enable-ftp –with-gd –with-gettext –with-gmp –with-ldap –enable-mbstring –with-mcrypt –with-mysql –with-mysqli –with-openssl –with-pdo-mysql –with-pspell –enable-shmop –enable-soap –enable-sockets –enable-sysvmsg –enable-wddx –enable-xml –with-xsl –with-zlib –with-config-file-path=/etc –with-config-file-scan-dir=/etc/php.d –with-libdir=lib64

●saslauthdの設定

「/usr/lib/sasl2」ではなく「/usr/lib64/sasl2」のを変更する。

# cd /usr/lib64/sasl2
# cp -a smtpd.conf smtpd.conf,20110401
# vi smtpd.conf
—- ここから —-
### START 2011/04/01 myname ###
#pwcheck_method: saslauthd
pwcheck_method: auxprop
### END ###
—- ここまで —-

●Squidの設定変更

「/usr/lib/squid/ncsa_auth」ではなく「/usr/lib64/squid/ncsa_auth」にする。

# cd /etc/squid
# cp -a squid.conf squid.conf,20110401
# vi squid.conf
—- ここから —-
### START 2011/04/01 myname ###
auth_param basic program /usr/lib64/squid/ncsa_auth /etc/squid/.htpasswd
### END ###
—- ここまで —-

Passengerのステータス確認ツールの紹介(その2)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

前回に引き続き、Passengerに標準でインストールされるステータス確認ツールの紹介をしたいと思います。

passenger-memory-stats

 passengerのプロセスのメモリの使用状況が見れます。出力内容がpassenger 3.0より変わったようで、3.0より前、3.0以降で以下のようになります。

3.0より前

-------------- Apache processes --------------
PID    PPID   Threads  VMSize   Private  Name
----------------------------------------------
16483  1      1        9.7 MB   0.2 MB   /usr/local/apache2/bin/httpd
22344  16483  1        10.0 MB  0.6 MB   /usr/local/apache2/bin/httpd
22693  16483  1        10.1 MB  0.6 MB   /usr/local/apache2/bin/httpd
22695  16483  1        10.4 MB  0.8 MB   /usr/local/apache2/bin/httpd
22710  16483  1        10.0 MB  0.5 MB   /usr/local/apache2/bin/httpd
22711  16483  1        10.4 MB  0.8 MB   /usr/local/apache2/bin/httpd
22712  16483  1        10.0 MB  0.5 MB   /usr/local/apache2/bin/httpd
22726  16483  1        10.1 MB  0.6 MB   /usr/local/apache2/bin/httpd
22729  16483  1        10.1 MB  0.6 MB   /usr/local/apache2/bin/httpd
22746  16483  1        10.0 MB  0.4 MB   /usr/local/apache2/bin/httpd
22751  16483  1        10.0 MB  0.4 MB   /usr/local/apache2/bin/httpd
22768  16483  1        10.0 MB  0.5 MB   /usr/local/apache2/bin/httpd
22770  16483  1        9.8 MB   0.3 MB   /usr/local/apache2/bin/httpd
22771  16483  1        9.8 MB   0.2 MB   /usr/local/apache2/bin/httpd
22772  16483  1        9.8 MB   0.2 MB   /usr/local/apache2/bin/httpd
### Processes: 15
### Total private dirty RSS: 7.11 MB

--------- Passenger processes ---------
PID    Threads  VMSize   Private  Name
---------------------------------------
16505  13       7.6 MB   0.6 MB   /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/ext/apache2/ApplicationPoolServerExecutable 0 /usr/lib/ruby/gems/1.8/gems/passenger-2.1.3/bin/passenger-spawn-server  /usr/bin/ruby  /var/rails/tmp/passenger.16483/info/status.fifo
16506  1        7.4 MB   4.5 MB   Passenger spawn server
17566  1        48.1 MB  35.5 MB  Rails: /var/rails/huga
19798  1        53.7 MB  39.7 MB  Rails: /var/rails/hoge
19800  1        51.1 MB  37.3 MB  Rails: /var/rails/hoge
22320  1        37.9 MB  30.1 MB  Passenger ApplicationSpawner: /var/rails/huga
22325  1        51.0 MB  37.2 MB  Rails: /var/rails/hoge
22327  1        52.4 MB  38.5 MB  Rails: /var/rails/hoge
22329  1        37.6 MB  29.6 MB  Rails: /var/rails/hoge
### Processes: 9
### Total private dirty RSS: 252.97 MB

項目の説明

VMSize

仮想メモリ領域のサイズPrivate

ディスクとの同期が取れていない物理メモリの領域のサイズ(dirtyと表記されるもの) .

3.0以降

--------- Apache processes ----------
PID    PPID  VMSize   Resident  Name
-------------------------------------
644    1     15.6 MB  7.5 MB    /usr/apache2/2.2/bin/httpd
25364  644   15.0 MB  4.1 MB    /usr/apache2/2.2/bin/httpd
652    644   15.0 MB  4.1 MB    /usr/apache2/2.2/bin/httpd
653    644   15.0 MB  4.3 MB    /usr/apache2/2.2/bin/httpd
655    644   15.0 MB  4.3 MB    /usr/apache2/2.2/bin/httpd
656    644   15.0 MB  4.3 MB    /usr/apache2/2.2/bin/httpd
25282  644   15.0 MB  4.3 MB    /usr/apache2/2.2/bin/httpd
25706  644   15.0 MB  4.3 MB    /usr/apache2/2.2/bin/httpd
26280  644   14.9 MB  2.9 MB    /usr/apache2/2.2/bin/httpd
25284  644   15.0 MB  4.3 MB    /usr/apache2/2.2/bin/httpd
25283  644   15.0 MB  4.3 MB    /usr/apache2/2.2/bin/httpd
6255   644   15.0 MB  4.3 MB    /usr/apache2/2.2/bin/httpd


-------- Nginx processes ---------



---- Passenger processes ----
PID  VMSize   Resident  Name
-----------------------------
648  4.6 MB   3.0 MB    PassengerWatchdog
649  5.5 MB   4.0 MB    PassengerHelperAgent
651  10.6 MB  5.2 MB    PassengerLoggingAgent

 ApacheとNginxとWebサーバーのプログラムごとで表示されるようになりました。自分の検証環境はApacheで動作させているので、Nginxで動いているプロセスは表示されていません。

項目の説明

VMSize

仮想メモリ領域のサイズResident

物理メモリの領域のサイズ.

 また、3.0より前のバージョンだとapxs, httpdにパスが通ってないとエラーになり実行できません。

 その場合、

 $ APXS2=[apxsのパス] passenger-memory-stats

か、または、

 $ HTTPD=[httpdのパス] passenger-memory-stats

とすれば、実行できます。また、root権限で実行しないとPrivateの合計が取得できず表示が以下のようになります。

 ### Total private dirty RSS: 0.00 MB (?) 

 サイトの動きが怪しい時など、前回紹介したpassenger-statusと合わせて使ってもらえると、怪しいプロセスを見つけるのに便利かと思います。それでは。

アリペイの導入について-即時支払方法の実装

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

アリペイ支払いにも3種類があります。

(ネット上すでにrails開発用のプラグインがあるようです)

今日はそのうちに、一番簡単な即時支払いについてご紹介します。即時支払いというはエンドユーザが支払った金額はすぐ売り方のアリペイアカウントに入る支払いで、
要求/応答パタンです。

一.アリペイ支払い用のデータの用意
パラメータ説明
必須パラメータ:
1.service:api名称、”create_direct_pay_by_user”、固定の文字列
2.partner:パートナーID、アリペイ社が発行する売り方のID
3.return_url:エンドユーザがアリペイシステムで支払完了後、パートナーシステム(売り方)に戻る時のURL
4.out_trade_no:注文番号などのパートナーシステムにユニックの注文識別番号
5.subject:商品名称
6.total_fee:合計金額(priceと同時に渡せない)
7.payment_type:1で固定
8.seller_email:パートナーシステム(売り方)がアリペイに登録する時のメールアドレス(seller_idでもOK)
9.sign:パラメータをサインする後の値
10.sign_type:サインアルゴリズム

ここではパラメータのサインについて説明する必要があります。
1、パラメータ名の昇順(signとsign_type以外)でソートする。
パラメータ名が同じ場合、パラメータ値の昇順でソート。

2、アリペイ社が発行するパートナーの秘密キーを直接接続

3、指定のsign_typeで、サインする

例、
out_trade_no=20111111111111
partner=2088123456789000
payment_type=1
return_url=http://example.com/alipay/alipay_return.jsp
seller_email=taro@example.com
service=create_direct_pay_by_user
subject=AAA
total_fee=0.01
秘密キー:abc123

サイン前のパラメータは下記になります。
out_trade_no=20111111111111&partner=2088123456789000&payment_type=1&return_url=http://example.com/alipay/alipay_return.jsp&seller_email=taro@example.com&service=create_direct_pay_by_user&subject=AAA&total_fee=0.01abc123

※サイン用のパラメータ値はURLエンコードしないでください。


二、連携用URLを生成、エンコード、連携する

上記の1~10までパラメータを接続して、特殊記号が入っている場合、エンコードする必要があります。

一番基本的なものをご紹介しました。
上記の1~10以外、いろいろパラメータが渡せます。必要に応じてアリペイ社のドキュメントをご参照ください。

リンク画像をonmouseを使わずにcssで変化させるTips

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

リンクになっているバナーなどの画像を簡単にonmouseで変化させたい時のちょっとしたTipsです。


マウスオーバーで切り替えたいとき、
普通は画像を別途用意してjavascriptのonmouse処理を使って切り替えます。
でもやんごとない事情で画像を用意できない時もあります。
それでも変化させたい!
そんな時はcssで透明度を指定することで
あたかもonmouse属性を使っているかのようなフリをすることができます。

cssは簡単。
a:hover img {
    filter: alpha(opacity=75);
    opacity:0.75;
}

これだけ。
数字はゼロに近づくほど透明になります。
画像を半透過させることで変化をつけているので、
背景に柄があったり背景色と混ざってへんな色になったり、
そもそも画像の一部だけ変化させたいということには対応できませんが
画像が用意できないなど取り急ぎ必要なときにはちょっと使える小技です。

ctagsを使ってみました

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ctagsとはソース内の変数やメソッドを解析し、インデックスを作成するツールです。

インデックスを作成しておくと、Vimなどで指定のキーを叩くことで、現在のカーソル位置

にある変数やメソッドの定義にジャンプすることができます。

 ctagsのインストール(MacOS Xの場合)

MacOS X 10.3 以降では標準でctagsがインストールされていますが、BSD由来のもので

一部オプションが使えなかったりするので、Exuberant Ctagsをmac portsでインストールします。

$ sudo port install ctags

インストールできたら以下のコマンドで対応している言語を見てみましょう。

$ ctags --list-languages
C
C++
C#
Cobol
DosBatch
Eiffel
Erlang
Flex
Fortran
HTML
Java
JavaScript
Lisp
Lua
Make
MatLab
OCaml
Pascal
Perl
PHP
Python
REXX
Ruby
Scheme
Sh
SLang
SML
SQL
Tcl
Tex
Vera
Verilog
VHDL
Vim
YACC

 タグの作成

今回はRubyのコードを解析してタグを作成してみます。

Railsのアプリケーションルートに移動します。

$ cd [RAILS_ROOT]

タグを作成します。

※コマンド実行の前に、ctagsのパスが/opt/local/bin/ctagsになっていることを確認してください

$ ctags -R

アプリケーションルートディレクトリ直下にtagsというファイルができたはずです。

試しに、tagsファイルを作成したアプリケーションで適当なファイルをVimなどで開き、

ctrl + ] を打ってみてください。

カーソル位置にあるメソッド定義にジャンプできます。

これでエディタでのコーディングが少し楽になります。

以上です。

GCALDaemonを使って、ical対応アプリケーションとGoogleカレンダーを同期する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

弊社にて販売しているSNSパッケージはスケジューラとして社内で利用されていますが、icalデータとして出力するインターフェースも持ち合わせているので、折角だからGoogleカレンダーと同期をとって利用したいと思います。

GCALDaemonというソフトウェアを利用すれば、比較的簡単に同期が実現できます。

今回は Mac OS X 10.6 上で設定を施してみたいと思います。

 必要なもの

  • Java 1.5 以上のランタイム環境
  • Gmailのアカウント
  • iCal 互換のアプリケーション

 Mac OS X へのインストール

http://sourceforge.net/projects/gcaldaemon/files/linux/ からLinux用バイナリzipをダウンロードし、

mkdir -p ~/gnu/ などとしてインストール用ディレクトリを作成します。

そこで以下のオペレーションを実行します。

cd ~/gnu
unzip ~/Downloads/gcaldaemon-linux-1.0-beta16.zip
chgrp -R admin ~/gnu/GCALDaemon
chmod -R g+w ~/gnu/GCALDaemon
chmod 755 ~/gnu/GCALDaemon/bin/*.sh

設定をテストするため、以下のコマンドを実行します。

cd ~/gnu/GCALDaemon/bin
 ./password-encoder.sh
Your Google password: Googleアカウントのパスワードを入力します

Original password: 上で入力したパスワードが表示されます
Encoded  password: xxxxxxxxxx ここで出てきた文字列を後ほど利用します

Sample configuration options for GCALDaemon:

file.google.password=xxxxxxxxxx
ldap.google.password=xxxxxxxxxx

notifier.google.password=xxxxxxxxxx
sendmail.google.password=xxxxxxxxxx
mailterm.google.password=xxxxxxxxxx

この後で設定ファイルも編集します。~/gnu/GCALDaemon/conf/gcal-daemon.cfg を開いてください。

% diff -U0 gcal-daemon.cfg.default gcal-daemon.cfg
--- gcal-daemon.cfg.default     2011-05-23 20:36:16.000000000 +0900
+++ gcal-daemon.cfg     2011-05-23 20:42:32.000000000 +0900
@@ -62 +62 @@
-file.ical.path=/usr/local/sbin/GCALDaemon/google.ics
+file.ical.path=/Users/myname/gnu/GCALDaemon/ical.ics
@@ -65 +65 @@
-file.google.username=example@gmail.com
+file.google.username=myname@gmail.com
@@ -68 +68 @@
-file.google.password=328$$gbv1WZhRGbhN2Z
+file.google.password=047$hogehogehog
@@ -71 +71,2 @@
-file.private.ical.url=/calendar/ical/example%40gmail.com/private-495cf94a5c0f1bfg/basic.ics
+file.private.ical.url=/calendar/ical/myname%40gmail.com/private-f1ldld54d7f9888316e6dlflf9ldld8hoge/basic.ics
+

設定差分は上記の通りです。

また、file.private.ical.urlに関してはGoogleカレンダーの設定から「限定公開URL」のICALリンクをクリックしてでてきた文字列のhttps://www.google.com/以降の文字列をペーストしてください

ここまでで基本的な設定はできました。一度きちんと同期ができるか、以下のコマンドを実行してみてください。

% ~/gnu/GCALDaemon/bin/sync-now.sh

コマンドを実行した後、ical.icsファイルの内容がGoogleカレンダーに反映されていたら成功です。

icalファイルを出力するアプリケーションに対してwgetやcurlなどでファイルをgetするようcrontabにしかけておきます。

% crontab -l
0 * * * * (cd ~/gnu/GCALDaemon ; curl -O http://sns.kbmj.jp/users/myname/calendar/ical.ics ; /Users/myname/gnu/GCALDaemon/bin/sync-now.sh ) > /dev/null 2>&1

これで1時間おきに同期がおこなわれた事になります。

他にもいろんなパターンでカレンダー同期がGCALDaemonで出来ますので、是非試してみていただければと思います。

nodeJS 〜nodeJSとは?〜

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rick No22です。
今回はnodeJSついてです。
nodeJSとは?nodeJSが生まれた経緯等話していきます。

nodeJSとは?

「JavaScriptを用いたNon-blocking I/O環境」です。

Non-blocking I/Oとは?

データの送受信を行う際に、完了せずに他の処理を開始する通信方式です。
例えるならば、
洗濯機を動かしつつ掃除して完了したら洗濯物を干すといったながら作業のようなものです。

nodeJSが生まれた経緯

「C10k問題対策用」としてnodeJSは誕生しました。
※ Cは「Client」10kは「1万台」を表しており「クライアント1万台問題」ともいわれています。

C10k問題とは?

クライアントの数が多すぎてサーバがパンクする問題です。
2009年当時、「apache」vs「nginx(エンジンエックス)」という構図がありました。
※apacheはスレッド方式、nginxはイベントループ

apacheのスレッド

スレッドはクライアントが増加するごとにスレッドが増加し、
スレッドが増加するごとにメモリの使用率が増加。

nginxのイベントループ

全ての実行要求を一つのキューに保存し、一つ一つ実行していく。

スレッドは使用するユーザが増えれば増えるほどメモリをくうため、イベントループのnginxが有利という形になりました。
しかし、イベントループにも弱点があります。

実行できる要求が一つのみになるということは、
その一つの処理が遅いと他の処理もその分遅れてしまうことになります。
この問題を解決しようと考えたのがそもそものnodeJSの始まりです。
ではどうやって解決したのか?
その答えは最初に述べた「Non-bloking I/O」が使用されます。
Non-bloking I/Oを使用することにより、
実行要求をそれぞれ平行して処理することを可能にしました。
イベントループを採用している言語は他にもあり、
Python:Twisted
Ruby:EventMachine
Perl:CokoのAnyEvent
などがあるが、
Non-blocking I/Oは強制されていない。
このNon-blocking I/Oを強制したものがnodeJSです。

ためしに触ってみたい方は、
はじめての共同作業 Canvas編がおすすめです。
これを使用するにあたって1点注意点が有ります。
nodeJSなど使用するものすべて最新で動かすことができますが、
落としたファイルをそのまま起動させようとすると
TypeError: Object #

rspec で、referer や user_agent 関連の機能もテストしよう

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

お恥ずかしながら、TDDを行わずにRailsで開発を行い続けてきたred です。最近、自分でも spec を書く用になりました。かなり捗ります。まだの方、お早めに。

自分にとって、spec を覚えるにあたっての最大の難関は、参考になる情報をなかなか見つけられなかった、ということでした。

結局、自分は、プロジェクトメンバの書いたものをコピペ改変することにより覚えました。

もし、独学の方、まわりにspec を書いている方のいない Rails/Ruby プログラマの方、まずはこのブログの記述もしくは下の私のコードを写経してみて、そこから、RSpec on Rails の使い方を調べるのが、導入によろしいかと思います。

=====

これ以下の内容は、下記環境にて動作確認をしています。

  • ruby 1.8.7
  • rails 2.1.0
  • rspec 1.3.0
  • rspec-rails 1.3.2

=====

直近のプロジェクトでは、ユーザエージェントやリファラを見て、それによって LPO を行うナビゲーションを実装していました。

つまりは、下記のような機能を実装しました。勿論、本物はもっと高機能です。

#{RAILS_ROOT}/app/controllers/test_controller.rb

class TestController < ApplicationController

  # リファラより、どの検索エンジンから流入したかを特定
  def referer
    referer = request.env['HTTP_REFERER']
    if referer.blank?
      @engine = "no referer"
    elsif referer.split("?")[0].include? "google"
      @engine = "google"
    elsif referer.split("?")[0].include? "yahoo"
      @engine = "yahoo"
    else
      @engine = "not determined"
    end
    render :text => @engine
  end
 

  # ユーザエージェントより、どのブラウザよりアクセスしているかを特定
  def ua
    ua = request.env['HTTP_USER_AGENT']
    if ua.include? "MSIE"
      @browser = "ie"
    elsif ua.include? "Firefox"
      @browser = "firefox"
    elsif ua.include? "Chrome"
      @browser = "chrome"
    elsif ua.include? "Opera"
      @browser = "opera"
    elsif ua.include? "safari"
      @browser = "safari"
    else
      @browser = "others"
    end
    render :text => @browser
  end

end

上記のようなアプリがうまく動いているか確認する際、通常のブラウザで見ることが不可能な場合は、Live HTTP Headers や User Agent Switcher のようなツールを使い、ユーザエージェントやリファラを詐称してチェックするのがセオリーかと思います。

spec で上記テストを自動化したい場合、下記のように記述すれば実行することができます。

#{RAILS_ROOT}/spec/controllers/test_controller_spec.rb

require 'spec_helper'

describe TestController do
  
  describe "referer" do
    it "google 検索からの流入かどうか判別するテスト" do
      request.env["HTTP_REFERER"] = "http://www.google.co.jp/search?q=test"
      get "referer"
      response.should be_success
      assigns[:engine].should == "google"
    end
    
    it "yahoo 検索からの流入かどうか判別するテスト" do
      request.env["HTTP_REFERER"] = "http://search.yahoo.co.jp/search?p=test"
      get "referer"
      response.should be_success
      assigns[:engine].should == "yahoo"
    end
  end
  
  describe "ua" do
    it "firefox を使っているかどうか判別するテスト" do
      request.env["HTTP_USER_AGENT"] = "Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.0.17) Gecko/2009122116 Firefox/3.0.17 GTB6 (.NET CLR 3.5.30729)"
      get "ua"
      response.should be_success
      assigns[:browser].should == "firefox"
    end
    
    it "IE を使っているかどうか判別するテスト" do
      request.env["HTTP_USER_AGENT"] = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
      get "ua"
      response.should be_success
      assigns[:browser].should == "ie"
    end
  end
end

上記のように、get で controller/method にアクセスする前に、request.env の各項目の値を上書きすれば、該当のテストを作成することができます。

dev_machine:rails_root red$ spec spec/controllers/test_controller_spec.rb 
....

Finished in 0.065284 seconds

4 examples, 0 failures
dev_machine:rails_root red$ 

describe や it は配列の each の中での実行も出来るので、テストしたいユーザエージェントやリファラとその結果をDB化しておくことにより、いちいちツールを用いて切り替えることなく、一気にhttp_header 関連のテストが行えるようになりました。

参考:http://stackoverflow.com/questions/542856/how-do-i-set-http-referer-when-testing-in-rails

【FlashLite】機種依存の不具合や仕様について7つの事例。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

FlashLiteにはFlashLite固有の機種依存による不具合や仕様が数多く存在します。

今回は実際に自分が実際に直面した中から7つの事例をピックアップしてご紹介します。

(1) SH機種でFlashの再生が停止する

【現象】

・SoftBankのSH機種の場合は、画面が真っ白で表示(画像取得失敗と同様の表示)され、閲覧不可となる。
・DocomoのSH機種の場合は、「画像に誤りがあり、正しく動作しません」というメッセージが表示され、閲覧不可となる。

【原因】

無限ループが発生しているため。大半の携帯端末はFlash内で無限ループが発生した際に無視するが、一部SH機種はそのまま実行後、実行回数制限によりFlashの再生を停止する。

【解決方法】

無限ループが発生する場合のほとんどはコーディングミスである可能性が高いため、細かくtraceしながらデバッグを行うしかありません。
※次項にて意図しない無限ループが発生する特殊な事例についてご紹介しています。

(2) 一部端末で無限ループが発生する

【現象】

一部端末で無限ループが発生する

【原因】

「for(i=0; i < NaN; i++){}」となった場合に無限ループが発生するため。

【解決方法】

for文のlimit指定が「NaN」になっていないかどうかtraceをしながらデバッグするしかありません。 例えば、「int(“”)」等で「NaN」になっている可能性もあります。

(3) System.capabilities.hasSharedObjectsの判定結果が誤っている

【現象】

Panasonic製/TOSHIBA製のSoftbank端末で「System.capabilities.hasSharedObjects」を実行すると、Shared Object が利用できないにもかかわらず「true」が返される。
この結果を受けて、SharedObject.addListener を実行している場合はそのまま処理が停止する恐れがあるため注意が必要です。

【解決方法】

System.capabilities.hasSharedObjects と同等の判定を他の方法で行うことはほぼ不可能。

【代替案】

System.capabilities.hasSharedObjects の結果が「true」の場合に、SharedObject.addListenerを実行している場合、
一定時間Listenerが走らない場合は強制的にremoveListenerを実行後、次処理へ移行させる等の対応が必要です。
※設定時間が短すぎると、正常にデータをロード中の端末において読み込み完了前に次処理に強制移行されてしまうので注意が必要です。

(4) _rotationを指定すると、_xscale, _yscaleの値が勝手に変わってしまう

【現象】

_rotationにFloat型の数値を指定すると 対象MCの_xscale, _yscaleが伸縮されてしまう(_rotation後に_xscale, _yscaleを再定義する必要有り)

【発生例】

アナログ時計の針を動かす処理等

【原因】

45°毎の _rotation 指定しか保証されていないため(?)

【解決方法】

_rotation後に_xscale, _yscaleを再設定することで処理は増えてしまいますが、見た目の崩れを防ぐことができます。

(5) auの一部端末にてPOSTができない

【現象】

auの一部端末でPOST通信ができない

【発生例】

・swfから大量の入力テキストをPOSTでサーバーに送りたい場合等
・HTML内のPOSTが指定された検索フォームから検索した結果としてswfのページを表示させたい場合等

【解決方法】

なし

【代替案】

swfの前後の通信はGET形式で統一します

(6) デバイスフォントが勝手に縁取りされる

【現象】

古いSHARP製Softbank端末において、デバイスフォントの色を白に設定すると端末側で勝手に白で縁取りされてしまう
※参考:”【web creators】今“ 知っておくべき”ケータイサイト制作事情/第五回”:http://www.mdn.co.jp/di/articles/2145/?page=2

【解決方法】

なし
白デバイスフォントは使用しない、不具合が生じる機種は非対応機種とする等の対策が必要です。

(7) Docomoの文字コード

【現象】

Docomo端末からswf経由でマルチバイト文字が含まれるパラメータを送信した場合、端末によって文字コードがShift_JISのものとUTF-8のものがある

【発生例】

(例)「あ」をGETパラメータに付与した場合

(1) F905i

 swf内にてescape処理無しswf内にてパラメータ全体をescape処理swf内にてパラメータの名前, 値を個別にescape処理
パラメータの文字コードShift_JISパラメータとして認識されないUTF-8

(2) SH01-B

 swf内にてescape処理無しswf内にてパラメータ全体をescape処理swf内にてパラメータの名前, 値を個別にescape処理
パラメータの文字コードUTF-8パラメータとして認識されないUTF-8

通常、携帯HTMLサイトを構築する際にDocomo端末の場合はShift_JISのパラメータを受け取る前提で実装されることが多くありますが、 FlashLiteの場合、Docomo端末で表示されたswfからパラメータが送られた場合に、上記のようにパラメータの文字コードにばらつきがでてきます。

【解決方法】

暫定的に判別ロジックを組んではいますが、あまりスマートな方法ではないので公開は控えておきます…。

アリペイの導入について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近、アリペイを試験ECサイトへ導入しています。導入しながら、まとめて少しずつメモします。ご参考まで

PS:
エンドユーザ⇒例、ECサイトで注文者
パートナーシステム⇒例、ECサイト及び運用者

第一回

——————2011-03-11(金)晴れ—————————————-
1.概要
アリペイ外部向けAPIには2種類あり、
一つは外部からリクエストを受け取るAPIであり、受取APIと言い、
もうひとつはアリペイから外部に通知するAPIであり、通知APIと言う。

受取API、通知APIの例はこの後詳しく説明するのでここで省略

2.交互パタン
(1)要求/応答パタン
もっとも使われているパタンで、パートナーシステムからリクエストを送信して、アリペイシステムにて処理を行って、処理結果を同期にパートナーシステムに戻すこと。

画面上から見れば呼出と遷移に分かれて、
呼出:パートナーシステムがアリペイの関連APIを呼び出すこと
遷移:パートナーシステムからアリペイの支払い画面に遷移して、エンドユーザはアリペイ支払システムにて支払いを行うこと。

アリペイ支払処理完了後、またパートナーシステムに戻らせたい場合、パートナーシステムからアリペイAPIを呼び出す時、パラメータの一つとして、return_url(戻り先)を渡す必要があります。


・処理フローとしては、

・呼出先URL:
https://www.alipay.com/cooperate/gateway.do


(2)通知モード
エンドユーザがパートナーシステムからアリペイシステムに遷移して、アリペイシステムにて今回の操作を完了させる。(パートナーシステムに戻らない)
アリペイシステムはパートナーが関心しているイベント、ステータスなどをパートナーシステムに通知する。
アリペイシステムの処理結果を非同期に通知されたい場合、パートナーシステムからアリペイAPIを呼び出す時、パラメータの一つとして、notify_url(通知先)の指定が必要です。

例、エンドユーザがパートナーシステムにて注文して、アリペイシステムにて支払う。支払いステータスが変わる時、アリペイシステムから
最新の支払いステータスや関連情報をパートナーシステムに通知する。

・処理フローとしては

・1.アリペイシステムからパートナーシステム(通知URL:nofity_url)に通知する。
・2.通知到着後、パートナーシステムは通知ID(nofity_id)で通知の有効性をアリペイシステムに確認する。
・3.アリペイシステムは通知の有効性を判断して、判断の結果をパートナーシステムに戻す。(True/False)
・4.パートナーシステムは通知により処理を行い、処理結果をアリペイシステムに戻す。
・5.パートナーシステムから戻された処理結果によりアリペイシステムは処理を行う。

アリペイシステムはHTTP/HTTPSプロトコルのpostメソッドで、データをパートーナシステムに送信する。
通知URLはアリペイとの契約に静的に指定できる。通知URL(notify_url)が指定されたら、すべての通知を指定されたURLに通知する。
アリペイ通知失敗またはパートーナシステムから処理成功の応答がない場合、アリペイシステムは定期的(1分間、3分間、5分間、10分間…)にデータを再送するが、すべての通知がパートーナシステムに届けることを保証しない。
重複送信の可能性がある、かつ、必ず業務上に前後順位で通知するわけではないので、パートーナシステムには重複送信無視及びだたしくソートする処理が必要だ。通知を受け取って処理する前に本システムの処理ステータスなどで処理されたかどうか判断する。本システムの処理ステータスをチェックする時、データロックかタイムスタンプを見るのをお勧め。

2-2.通知検証
システムの安全性から考えると、パートーナシステムはアリペイの通知を受けると、通知の有効性を検証する必要がある。アリペイAPIが正しく利用されているのを保証するために、パートーナシステムが1分間以内(現状1分間、今後調整可能性もある)の通知のみ検証できる。
検証用URL:
HTTPSの場合
https://www.alipay.com/cooperate/gateway.do

検証リクエスト例
https://www.alipay.com/cooperate/gateway.do?service=notify_verify&partner=1234567890¬ify_id=abcdefghijklmnopqrst

HTTPの場合
http://notify.alipay.com/trade/notify_query.do
検証リクエスト例
http://notify.alipay.com/trade/notify_query.do?partner=1234567890¬ify_id=abcdefghijklmnopqrst

通知検証APIの出力パラメータ
出力内容    説明
Invalid        パラメータ無効
True        検証成功
False        検証失敗

——————————————————————————

まだまだありますが、今回はここまでです。☆.。*・゜゜‥*。.☆.。*・゜゜‥*。. ☆.。*・゜゜‥*

MacPorts で /opt/local/bin/perl が無くなってしまった時の対処方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは、たろちゃんです。MacPortsで/opt/local/bin/perlが無くなってしまってImageMagickがインストールできないという現象が起きたので対処してみました。

MacPortsは便利ですが、たまに依存関係などで問題が起きるケースがあります。

本日MacPortsをアップデートしたところ、ImageMagickがインストールできないというエラーが発生しました。

行ったコマンドは以下の通りです。

$ sudo port selfupdate
$ sudo port upgrade outdated

たったこれだけでエラーになりました。ログを確認すると”/opt/local/bin/perl”が存在しないため、ImageMagickのインストールに失敗しているようです。

Perlの変更点を確認したところ、“Changeset 76485”にて以下の修正があったのが原因のようでした。

change perl5.* ports to do +mangle_names by default
change perl5 to link perl5.x pieces to their non-mangled names
change perl5 to default to perl5.12

この修正点でperl5.12がデフォルトになるのですが、perl5.12側のアップデートの歳にperl5を消してしまうように動いてしまうため、/opt/local/bin/perlが消えてしまったようです。

なので、以下のようにしてperl5を再インストールしました。

$ sudo port install perl5

あとは先ほど失敗したupgradeをやり直してあげます。

$ sudo port upgrade outdated

これで無事ImageMagickがインストールされました。

なお、perl5はデフォルトでperl5.12を使うようになりますが、これはperl5のvariantsで設定された値がデフォルトで5.12ということになります。

Wisp:~ btm$ port variants perl5
perl5 has the variants:
   perl5_10: use perl 5.10 instead of perl 5.8 or perl 5.12
     * conflicts with perl5_12 perl5_8
[+]perl5_12: use perl 5.12 instead of perl 5.8 or perl 5.10
     * conflicts with perl5_10 perl5_8
   perl5_8: use perl 5.8 instead of perl 5.10 or perl 5.12
     * conflicts with perl5_10 perl5_12

perl5.8やperl5.10を使いたい場合は、variantsに指定してperl5をインストールすれば良いでしょう。

jQuery animation 〜動きのあるWebサイト作り〜

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rick No21です。
今回はjQueryでできる動きのあるサイトの作り方の一部をご紹介。

表示されている場所がおかしいかもしれませんが、表示されていますか?
ちなみにchromeでしか動作確認していません。
firefoxだとみれませんでしたw


では解説に入ります。

jQueryの読み込み

まずは、jQueryを読み込まないと始まりません。
< script type=”text/javascript” src=”http://search.kbmj.com/javascripts/jquery-1.4.2.min.js” >< /script >これによりjQueryを読み込みます。
自分で試すときは
http://jquery.com/
ここから落としてきてください。
本来は内に記述します。

表示場所

表示場所の指定
< div id=”box” title=”sample” > < /div>
< div id=”linkText” class=”lt” > < /div>

jQuery

< script language=”JavaScript” >< !–
URL = [1,2,3,4] //長いので省略
jQuery(function(){
  for (var i=1; i <= URL.length; i++) {
    jQuery(“#box”).append(‘< a href=”‘ + URL[(i – 1)] + ‘” >< div id=”box’+ i + ‘” class=”box” title=”sample’ + i + ‘” >< /div >’);
    move(“box” + i, i);
  };

  jQuery(“.box”).css({
    ”width”:”40px”,
    ”height”:”40px”,
    ”position”:”absolute”,
     “top”:”400px”,
    ”background-color”:”#FFCC66″,
    ”cursor”:”pointer”
  });

  jQuery(“.lt”).css({
    ”width”:”270px”,
    ”position”:”absolute”,
    ”font”:”bold 10pt monospace”,
    ”top”:”350px”,
    ”letter-spacing”:”2px”,
    ”margin”:”0px”,
    ”padding”:”5px”,
    ”border-top”:”dotted 2px #FFCC66″,
    ”border-bottom”:”dotted 2px #FFCC66″,
    ”display”:”none”
  });

  function move(id, count){
    jQuery(‘#’ + id).animate({“left”: (count * 100) + 200 + ‘px’});
  };

  jQuery(“.box”).hover(
   function(){
     jQuery(this).css({“background-color”:”#669933″});
     var tx = jQuery(this).attr(“title”)
     jQuery(“#linkText”).text(“->” + tx);
     jQuery(“#linkText”).show();
   },

   function(){
     jQuery(this).css({“background-color”:”#FFCC66″});
     jQuery(“#linkText”).text(“”);
     jQuery(“#linkText”).hide();
   }
  );
});
//– >< /script >

#boxに対しての動作

for (var i=1; i <= URL.length; i++) {
    jQuery(“#box”).append(‘< a href=”‘ + URL[(i – 1)] + ‘” >< div id=”box’+ i + ‘” class=”box” title=”sample’ + i + ‘” >< /div >’);
    move(“box” + i, i);
  };
内にURLの数だけ

タグを追加します。
  function move(id, count){
    jQuery(‘#’ + id).animate({“left”: (count * 100) + 200 + ‘px’});
  };
タグ追加後moveに引数でid名と現在地(何ループ目?)を引数に渡してmoveの処理を行います。
moveの処理は、その名の通りboxを動かします。
animateによって動きのある動作をcssで指定できます。
どのboxをで第1引数のidをどれだけ移動させるかに第2引数のcountを使用しています。

boxと#linkTextに対しての動作

  jQuery(“.box”).hover(
   function(){
     jQuery(this).css({“background-color”:”#669933″});
     var tx = jQuery(this).attr(“title”)
     jQuery(“#linkText”).text(“->” + tx);
     jQuery(“#linkText”).show();
   },
   
   function(){
     jQuery(this).css({“background-color”:”#FFCC66″});
     jQuery(“#linkText”).text(“”);
     jQuery(“#linkText”).hide();
   }
  );
hoverは、各boxにマウスが重なったとき、外れたときの動作です。
まずhoverの第1引数に記述されているのが、マウスが重なったときの処理です。
cssで背景を変更、タグのtitleを取り出して#linkTextに記述して表示しています。
第2引数は、マウスが外れたときの動作です。
cssで背景を元に戻して#linkTextの内容を空にして非表示にしています。

CSS
CSSの記述内容は割愛させていただきますが、本来は外部参照の方が綺麗ですね。

jQueryを使用するとこのような動きのあるサイトが簡単に作成可能です。<>

ブラウザ関連でひっかかった諸々のこと(主にjavascript)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

「結局、お客様にとってサービスの品質って、画面がどれだけ洗練されているか、なんだよね」

企画や営業担当の方からよく聞く言葉です。全くもってその通り。

でもエンジニアとしては、データの保存と加工、セキュリティを最初に気にしてしまいがち。だから「こそ」、画面のしっかいりしているサービスは「いいサービス」と言えるのでしょう。

というわけで、自分が携わってきた画面(ブラウザ)系のびっくりしたことを紹介します。

まず前提として、自分は普段このようなスタイルでコーディングを行っています。

  • 基本的にサーバサイドのアプリを作ることがメイン(Rails 以前はPHP)
  • よく使うブラウザは FireFox。LiveHttpHeaders と FireBugs に惹かれてそのまま
  • 開発機は MacOS。テスト用に Linux。windowsテスト機は共有

cookie制限の罠

自分が初めて本格的なjavascriptを書いたのは今から4年前。新卒で入社して1ヶ月が経ったGW前でした。作ったアプリは、画面上のガジェットを「開閉」できるようにする、という今ではよく有るもの。mixi では、ガジェットの右上をクリックして調整します。

open_close

今ではmixiも上記のガジェットはリアルタイムで行いましたが、当時はクリックするたびにリクエストが飛んでいるのを見て、

  「じゃぁ自分は遷移せずに変更/保存できるようにしまーす」

ととんでもないことを宣言した新入社員時代。しかも javascript は素人同然。「○日までに実現の目処が経たなかったら、遷移で実装してくださいね」と繰り返すリーダーを尻目に設計/実装してみたものFireFoxでは動くが IE6で動かない。

んで、その原因は何故かというと、自分はその実装で各ガジェットの状態をcookie で保存していたのですが、1ガジェットにつき1つのcookieを発行していました。それが、制限にひっかかっていました。

http://www.studyinghttp.net/cookies#Restriction

で、これを共有したときに「これだからIEは。。。」と言いそうになったのですが、

実はこれ、IEの方が本来のcookieの仕様(rfc)に忠実で、FFの方が拡大解釈をしている模様。そのため、設計(仮実装)のときにうまくいっていたのが、そろそろ出来そうかな、となった時点で大幅変更を加えるはめになりました(各ガジェットの状態を構造化し、jsonにして1つのcookieに保存)。

FFの「ゆるさ」というのも、後々問題になるというお話。

IE6のselect tag問題

IE7が出来て(普及して)一番うれしかったのが、この問題が解消されたこと。

これは、各タブを重ねたときに、IE6(以前)の場合はselectタグが1番上にきてしまう、というもの。このページの一番下を参照して下さい

で、iframe を使うという対応策は既に知られているのですが、 とはいっても複数ブラウザで競合チェックしたりというのはやっぱりめんどくさいです。

IE での position : fixed が効かない問題

こちらも、比較的有名なIEの不具合?仕様?でしょうか。こちらができると固定したサイドバー等が簡単に実装できるのですが(javascript で実現したものはわざとらしくて)、これはどうしようもないです。

fixed.jsというライブラリがありますが、それでもテストの心配はあるわけで、 その分の調査やデバッグの期間というのは長く取る必要がある、と経験上感じています。

上記のセレクトタグと併せて、javascriptとCSSでリッチな画面を作ろうとした場合に大問題となる場所ですので、その点、調整にはかなりの時間を確保しておく必要がある所です。

 json.stringify と prototype の喧嘩

2つ続けてIE6という古いブラウザの話をしましたが、今後は最近のブラウザの話。

前回の記事、 何か変なjson が吐かれるために苦労していましたが、そちら、やっと原因がつかめました。

現在担当しているプロジェクトではjavascript のライブラリはjQuery を主に使っているのですが、以前からの資産もありprototypeで実装されているものもあります。そのprototype のライブラリが json.stringify を汚染していた模様。

http://d.hatena.ne.jp/Gimite/20091129/1259495440

よって、今回は、json化は他のライブラリを使わず、その部分だけprototypeを使うように実装しました。

    var json = Object.toJSON(obj);

 ブラウザというよりもprototype.jsの問題ですが、高機能というのもアレなものだということで。

ajax 通信における post(本番) と get(開発時) の使い分け with firebugs

 rfc には含まれていないのですが、IE系では get で指定できるURLの長さは2083文字という制限があります。たしかにそれくらいの長さになるドメインやディレクトリはとても考えづらく、それくらい長いパラメータをつけるならpostにしろよ、というのは極々当たり前の常識的な判断ですので、特に疑問や憤りを覚えず他のブラウザの場合でも素直に従うべきでしょう。

ですが、ajax で非同期にページに一部だけ更新する場合、その通信は「開発期間の間は」getで行った方が特なことがあります。

Firefox で ajax 通信を行った場合、「接続」タブを開いた状態ではそのページでリクエストされた全てのコンテンツのリクエスト状況が表示されます。勿論、ajax でリクエストされたページも表示されます。

ajax で呼び出す URL(上記だと「ajax_body」)は、大抵の場合、Ruby(on Rails)等のサーバサイドの言語で動的に生成されています。勿論、開発中でバグや未実装があることも多いでしょう。そのリクエストが失敗した(500系のステータスコードが返ってきた)場合、上記のようにpostだと追跡が難しいです。

そのため、開発期間中だけでも get で ajax通信をするようにします。

このようにすると、上記の「ajax_body」にリクエストパラメータが付属してつくため、そのパーツとなるページだけ、別途ブラウザで表示し、デバッグを進めることができます。

最近のajax は、jQuery.ajax 等を用いて実装されるケースが多いと思われます。getとpostの切り替えに大幅な仕様変更を伴いませんので、ちょっとした参考にして下さいませ。勿論、リリース時より前、例えば負荷検証やUIテストの前には、post に戻しておく必要があります。

<script type=”???”>の怪奇

最後に、ちょっと脱力してしまったお話しを。

<script type=” text/javascript” language=”javascript”>〜</script> で囲まれたjavascript は、firefox, safari, chrome では実行されますが、IE系, Opera では実行されません。

つまり、

type の中が不正、つまり「(半角スペース)text/javascript」等、想定されていないものが入った場合、ブラウザ毎に挙動が異なります!!

お気をつけ下さい。

最近人気な記事