送受信_環境変数 ENV - 演習編

Problem5: 同一の閲覧者の連続した閲覧をカウントしないカウンターを作ってみよう

cookie を利用して、同じ閲覧者の連続したアクセスでカウントアップしない画像カウンターを作ってみてください

⇒ ヒント

Hint

  1. カウント値を閲覧者の cookie に保存しておいて、サーバーに保存されているカウント値と cookie から読み出されたカウント値が一致していたら、cookie を送信せず、カウントアップもしないという方法でやってみましょう
  2. 誰か他人がアクセスしてカウントアップするか、又は、cookie の寿命が来たら、カウントアップされる状態になります
  3. 作成の要領は普通のカウンターと、cookie カウンターを組み合わせるだけです
  4. 他の方法としては、カウントアップをロックするための cookie を、比較的短い寿命の設定で読み込ませておいて、その cookie が生きている間は、cookie を送信せず、カウントアップもしないというのも考えられます
  5. また、cookie を使わずに、閲覧者側の ipアドレスENV['REMOTE_ADDR']を読み取って、一時的にサーバーに記録し、一定時間、同一のipアドレスからのアクセスではカウントアップしないという方法もあります。ただ、最近は「プライバシーの保護」などの観点から、ネットワークのブロック毎にipアドレスの値が、同じ値になるように仮面を被ってしまったり、閲覧者が無線アクセスポイントなどを利用していると、同じ閲覧者ののアクセスでも移動や回線の都合で途中からipアドレスが変わってしまうなど、ipアドレスを手がかりにする方法は、あまりあてにならなくなってきています。

⇒ 答え

Solution

たとえば、こんなのでどうでしょう?

#!/usr/local/bin/ruby
countimg = "count.gif"
countlog = "count.txt"
Fonts    = Dir.glob("font/*.*").sort

begin
  f = File.open( countlog, "r")
  count = f.gets.to_i
  f.close
rescue
  count = 0
end

cookie = nil
unless /\bMYCOUNT=(\d+)\b/ =~ ENV['HTTP_COOKIE'].to_s && $1.to_i == count then
  count  += 1
  cookie  = "Set-Cookie: MYCOUNT=#{ count }; "
  cookie += ( Time.now + 60*60*12 ).gmtime.strftime("expires=%a, %d-%b-%Y %H:%M:%S %Z; ")
  cookie += "path=/; "
  cookie += "\n"
  File.open( countlog, "w").print count
  a = ["convert","+append"]
  for n in ("%03d" % count).split(//) do
    a += [ Fonts[n.to_i] ]
  end
  a += [countimg]
  r = system(*a) rescue false
  countimg = Fonts[0] unless r                      # カウンター画像の生成に失敗した場合の対策
  Process.waitall
end

countimg = Fonts[0] unless FileTest.file?(countimg) # カウンター画像が存在しなかった場合の対策

print <<EOS
Content-Disposition: filename="#{ ("%03d" % count) }.gif"
Content-type:   image/gif
Content-Length: #{ File.size( countimg ) }
#{ cookie }
EOS

f = File.open( countimg ,"rb")
STDOUT.binmode
while line = f.gets do
  print line
end
f.close

以上です。

Last updated 16.Sep.2006 [ Home ] [ Up ] [ 質問メール ]
Copyright © 2005-2006 Shigeru Konno All Rights Reserved..