JavaScriptによるRFC6570 - URI Templateの実装
JavaScriptで実装したのがdraftレベルのしか見つからなかったので作ってみました。
(↑Lv4まで対応してるのが有りました。でもせっかく作ったので引き続き公開しておきます。)
URI Templateって?
簡単に言うとURIに特化したテンプレートエンジンです。
「http://www.example.com/users/{userid:1}/{userid}/」って書いといて「http://www.example.com/users/t/test/」って文字列作れたら便利だよね!?
詳しくは以下を参考にしてください。
以下からお持ち帰りください。
githubもjsdo.itも初めて使うのでおかしかったら教えてください。
スクリプト本体はこちら
gitgub→https://github.com/s025236/URI-Template
jsdo.it→http://jsdo.it/s025236/URI-Template-0.1
テストコードはこちら
→http://jsdo.it/s025236/URI-Template-0.1.test
使い方
まずはscriptタグでロードします。
<script src="https://raw.github.com/s025236/URI-Template/master/URI-Template.js"></script>
あとはURI_Template::parseするだけです。
//window.useridを参照してパース結果を返します。 URI_Template::parse('http://www.example.com/users/{userid}/'); //オブジェクトを参照してパース結果を返します。 URI_Template::parse('http://www.example.com/users/{userid}/',{'userid' : 'test'});
仕様と不一致
RFC内に色々サンプルがあるのですが以下の理由によりいくつかテストが通りません。
- JavaScriptに「!」はエスケープしないけど「/」はする関数なんて知らないよ…
- OPコードが「;」の時だけなんで処理違うの?RFCがおかしいきがする。
最後に
応援コメントお待ちしております。
不具合報告や使用例等ありましたら、是非ご連絡ください。
携帯やスマートフォンでコンテンツを切替える"魔法"のapache設定 #apache
リキッドデザインとかレスポンシブウェブデザイン流行ってるけどやっぱりPC,スマートフォン,携帯(ガラケー)は別に別にコンテンツ用意したほうが良い時もありますよね。
でも「SEOとか考えると…」「URLがばらばらになっちゃって…」なんてお客様のお悩みを解決する為にいまさら感がすごいですが魔法の設定をご用意いたしました!
apacheの設定を書き換えよう
httpd.confで以下を書くだけでOKです。
virtualhostとかしてるときは適切に気書き換えてね。
##################################################################### #(C)makoto@2ch.to LoadModule rewrite_module modules/mod_rewrite.so LoadModule setenvif_module modules/mod_setenvif.so #browser判定 BrowserMatchNoCase "DoCoMo|KDDI|UP\.Browser|Vodafone|J\-PHONE|MOT\-|SoftBank|WILLCOM|DDIPOCKET" browser=mb BrowserMatchNoCase "Android|BlackBerry|iPhone|iPod|Windows Phone|IEMobile" browser=sp SetEnvIf browser ^$ browser=pc #URLがsp,pc,mb,commonから始まってない時だけ書き換える RewriteEngine on RewriteLog "logs/rewrite_log" RewriteLogLevel 0 RewriteCond %{REQUEST_URI} !^/(sp|pc|mb|common) RewriteRule ^/(.*) /%{ENV:browser}/$1 [PT]
※UA判定ルールは時代で変わるので新鮮な情報を調べてね
コンテンツをアップロードしよう
コンテンツの配置にちょっと工夫が必要です。
- (ドキュメントルート)/pc/ …PC向け
- (ドキュメントルート)/sp/ …スマフォ向け
- (ドキュメントルート)/mb/ …携帯向け
- (ドキュメントルート)/common/ …共通のファイル
リンクの仕方に気をつけよう
「(ドキュメントルート)/(pc|mb|sp)/index.html」には
・http://サーバ/index.html
・http://サーバ/pc/index.html
というアクセスパターンがあるので基本的に相対pathでコンテンツ作ってください。
commonは共通パーツ置き場で必ず絶対pathで指定します。
URLはどうなるの?
といった、公開するURLはPC,SP,MBをつけないでください。
でOKです。
- http://サーバ/pc/
- http://サーバ/mb/
- http://サーバ/sp/
- http://サーバ/common/
に明示的にアクセスがある場合自動判定しませんので「PC版はこちら」みたいな誘導が可能です。
注意事項
自動判定を効率的に使うためpc,sp,mbは可能な限りディレクトリ構成を同じにしてください。
PCの1ページが携帯だと複数ページに分かれる事が多いのでファイル名は仕方ないと思います。(…ができるだけ統一)
外部サイトからのリンクは可能な限り、端末名(pc/,mb/,sp/)をつけずファイル名も指定しない(DirectoryIndexをうまく使う)ようにしてください。
関連リンク
僕が考えた最強のサーバ設定もお役に立つと思いますので是非はてなブックマークをお願いします。
最後に
はてなブックマークだと返事やお礼が大変なのでtwitterかコメでお願いします。(twitterが嬉しいです)
こういう話出来る人が周りにすくないので是非twitterで語り合いましょう。
@s025236をフォロー
僕が考えた最強のサーバ設定
いつの間にかさくらのVPSの標準OSがCentOS6になってたので設定を見直してみました。
月額980円/月から利用でき、2週間のお試し期間もあるのでこれを機会にサーバ設定に足を踏み入れてみてはどうでしょう?
慣れると10分くらいでウェブサーバが立ち上げれるようになります。
すみません。こんなに多くの人が見てると思わなかったんです。
お一人様サーバ向けのつもりで書いてます。
タイトルもタグもネタだったのにツッコまれまくりで恥ずかしい…
公開鍵登録しよう
どうせ自分しか触らないなしrootで作業しちゃってもいいんじゃない?
リブート(またはsshのrestart)以降秘密鍵がないとsshでログイン出来なくなるので気をつけてください。
mkdir ~/.ssh/ touch ~/.ssh/authorized_keys chmod 700 ~/.ssh/ chmod 600 ~/.ssh/authorized_keys echo 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEA5BqkP+ToroYtzOhnZ2aOJj8WqUpRcQRy/D2ojlPsQutM9Pqfo3qI+75iLpTAAkt+X0RlSBNFLfLsDgfV45IWS/5jv7CKLF/AAIU8Ke5wKVXZrC1LkZ7HfnluALhepUkeB3ilrhFQS+qeS8LHw2s2C2Ig/bGj8lXuEyt93aSREIU= makoto@2ch.to' >> ~/.ssh/authorized_keys echo 'OPTIONS="-o PermitRootLogin=without-password -o GSSAPIAuthentication=no -o PasswordAuthentication=no"' >> /etc/sysconfig/sshd
※公開鍵は自分のに書き変えてね
id:itochan315さんから
普段からrootで作業しないのには誤操作防止の意味もあるのに、必要な時にsudoすればいい話ですよ。。
と指摘を頂きました。
個人的にはお一人様サーバだとsudoは形骸化してしまってると思ってます。
やっぱ日本人だし日本語だよね
echo 'LANG="ja_JP.UTF-8"' >> /etc/sysconfig/i18n
いらない子
yum -y remove '*.i[3-6]86' yum -y remove mlocate cups dhclient kudzu wireless-tools chmod -x /etc/cron.daily/makewhatis.cron chkconfig cpuspeed off
IPv6…なにそれ美味しいの?
echo 'IPV6_DEFAULTDEV=tun6to4' >> /etc/sysconfig/network echo 'IPV6INIT=yes' >> /etc/sysconfig/network-scripts/ifcfg-eth0 echo 'IPV6TO4INIT=yes' >> /etc/sysconfig/network-scripts/ifcfg-eth0 echo 'IPV6TO4_RELAY=192.88.99.1' >> /etc/sysconfig/network-scripts/ifcfg-eth0 echo 'tun6to4 2000::/3' >> /etc/sysconfig/static-routes-ipv6 echo 'IPV6TO4_IPV4ADDR='`/sbin/ifconfig eth0 |grep 'inet addr:' | awk '{print \$2}' | sed -e 's/addr://g'` >> /etc/sysconfig/network-scripts/ifcfg-eth0 echo 'UseDNS no' >> /etc/ssh/sshd_config
アクセス時間なんかいらなくね?
(2012/03/07 16:10 修正)
HDD遅いしイジメ良くない。noatimeをつけよう。
id:sh2さんから、はてなブックマークで
「RHEL 6系はrelatimeが導入されたのでnoatimeは設定しなくていいはず。」
という指摘を頂きました。(参考)
CentOS5からの惰性で書いててすみませんでした。
漏れまくりだけどファイアーウオール
どうせ不要なサービスとか動かさないしぃとかいわないで一応default dropで設定します。
/etc/sysconfig/iptablesと/etc/sysconfig/ip6tablesを書き換えます。
IP指定がなければ同じ内容で良いみたい。
###################################################################### # makoto@2ch.to *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] ###################################################################### # ループバック/ICMP/確立済みの接続 -A INPUT -i lo -j ACCEPT -A OUTPUT -o lo -j ACCEPT -A INPUT -p icmp -j ACCEPT -A OUTPUT -p icmp -j ACCEPT -A INPUT -p ipv6 -j ACCEPT -A OUTPUT -p ipv6 -j ACCEPT -A INPUT -p ipv6-icmp -j ACCEPT -A OUTPUT -p ipv6-icmp -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT ###################################################################### # OUTPUT -A OUTPUT -m state --state NEW -p tcp --dport ssh -j ACCEPT -A OUTPUT -m state --state NEW -p tcp --dport smtp -j ACCEPT -A OUTPUT -m state --state NEW -p tcp --dport domain -j ACCEPT -A OUTPUT -m state --state NEW -p udp --dport domain -j ACCEPT -A OUTPUT -m state --state NEW -p tcp --dport http -j ACCEPT -A OUTPUT -m state --state NEW -p udp --dport ntp -j ACCEPT -A OUTPUT -m state --state NEW -p tcp --dport https -j ACCEPT -A OUTPUT -m state --state NEW -p tcp --dport mysql -j ACCEPT #↓memcached #-A OUTPUT -m state --state NEW -p tcp --dport 11211 -j ACCEPT ###################################################################### # 公開ポート 必要なこだけコメントを外すこと #-A INPUT -m state --state NEW -p tcp --dport smtp -j ACCEPT #-A INPUT -m state --state NEW -p tcp --dport domain -j ACCEPT #-A INPUT -m state --state NEW -p udp --dport domain -j ACCEPT -A INPUT -m state --state NEW -p tcp --dport http -j ACCEPT #-A INPUT -m state --state NEW -p tcp --dport https -j ACCEPT #↓可能ならSAFTYを利用する #-A INPUT -m state --state NEW -p tcp --dport ssh -j ACCEPT ###################################################################### # 信頼できるIP -N SAFETY -A SAFETY -m state --state NEW -p tcp --dport ssh -j ACCEPT -A SAFETY -m state --state NEW -p tcp --dport smtp -j ACCEPT -A SAFETY -m state --state NEW -p tcp --dport http -j ACCEPT -A SAFETY -m state --state NEW -p tcp --dport https -j ACCEPT -A SAFETY -m state --state NEW -p tcp --dport mysql -j ACCEPT -A SAFETY -m state --state NEW -p tcp --dport 11211 -j ACCEPT -A SAFETY -m state --state NEW -p tcp --dport postgres -j ACCEPT -A INPUT -s 自分ちの固定IP -j SAFETY COMMIT
※CentOS5系だとip6tablesでRELATED,ESTABLISHEDが使えないので注意が必要です。
nginxさんは早くてかっこいい
SSLv2有効にしてるサイトが多くてビビる。
静的コンテンツならnginxで返してそれ以外はバックエンドに送る設定が多いけどちょっとひねってみた。
ファイルがあればnginxが返すけど特定の拡張子はバックエンドへ送る。not foundも裏に送る。
yum -y install nginx chkconfig nginx on cat > /etc/nginx/nginx.conf
###################################################################### # (c)makoto@2ch.to user nginx; worker_processes 2; pid /var/run/nginx.pid; error_log /var/log/nginx/error.log; events { worker_connections 1024; } ###################################################################### # http { #################################################################### # 上位サーバの設定 upstream backend { server 127.0.0.1:8080; } #################################################################### # 基本設定 include mime.types; sendfile on; tcp_nopush off; server_tokens off; keepalive_timeout 1; #################################################################### # 不要ならoff ssi on; ssi_types text/x-server-parsed-html; #################################################################### #圧縮しないならoff gzip on; gzip_vary off; gzip_disable “MSIE [1-6]\.”; gzip_disable “Mozilla/4″; gzip_types text/plain text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript ; #################################################################### # SSLの設定 ssl_certificate /etc/pki/tls/certs/localhost.crt; ssl_certificate_key /etc/pki/tls/private/localhost.key; ssl_protocols TLSv1.2 TLSv1.1 TLSv1; #SSLv2,SSLv3は脆弱性がある ssl_ciphers HIGH:!ADH:!MD5:!SSLv3; # openssl ciphers -v 'HIGH:!ADH:!MD5:!SSLv3' #nginxのversionによってssl_ciphersがエラーになる場合がある #ssl_ciphers HIGH:!ADH:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; #################################################################### # 80,443ポート server { index index.php index.html; root /var/www/html; listen 80; listen 443 ssl; #不要な場合はコメントアウト ################################################################## # backendでSSLか判定するのに必要 set $ssl 0; if ($scheme = 'https') { set $ssl 1; } proxy_set_header X-SSL $ssl; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ################################################################## # 静的コンテンツはブラウキャッシュ location ~ \.(gif|jpg|png|swf|css|js|txt|ico|css|html|xml)$ { expires 1d; } ################################################################## # not foundやcgi,php,plはバックエンドに渡す error_page 404 = @fallback; location ~ \.(cgi|php|pl)$ {proxy_pass http://backend;} location @fallback {proxy_pass http://backend;} } }
error_pageのエラーコードの後に=を追記しました。
POODLE対策の為SSLv3を禁止にしました
バックエンドはapacheが楽だよね
今までのknow howもあるし、rewrite使いたいし余計なこと考えたくない!
ZendFrameworkに興味がない人やそもそもphpに興味がない人は不要なとこは消して実行してね。
yum -y install php-ZendFramework-Cache-Backend-Memcached php-ZendFramework-Cache-Backend-Apc php-ZendFramework-Db-Adapter-Mysqli php-mbstring mod_extract_forwarded mod_ssl echo 'date.timezone = Asia/Tokyo' >> /etc/php.d/local.ini chkconfig httpd on cat > /etc/httpd/conf/httpd.conf
# (C) makoto <makoto@2ch.to> ###################################################################### # 基本設定 ServerRoot /etc/httpd PidFile run/httpd.pid User apache Group apache # 接続関係 Timeout 3 KeepAlive off KeepAliveTimeout 1 MaxKeepAliveRequests 20 #Listen 0.0.0.0:80 Listen 127.0.0.1:8080 # 起動設定 <IfModule prefork.c> StartServers 3 MinSpareServers 5 MaxSpareServers 10 MaxClients 100 MaxRequestsPerChild 0 </IfModule> # 起動設定 <IfModule worker.c> StartServers 2 MaxClients 150 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 </IfModule> # その他 ServerTokens Prod ServerSignature Off TraceEnable Off ###################################################################### # ディレクトリの設定 AccessFileName .htaccess DocumentRoot /var/www/html/ ###################################################################### # MIME/言語設定 LoadModule mime_module modules/mod_mime.so LoadModule mime_magic_module modules/mod_mime_magic.so TypesConfig /etc/mime.types MIMEMagicFile conf/magic DefaultType text/plain ###################################################################### # LOG設定 ErrorLog logs/error_log LogLevel warn #LogLevel error #LoadModule log_config_module modules/mod_log_config.so #LogFormat "%h %v %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %X%D" combined #CustomLog logs/access_log combined env=!nolog ###################################################################### # php <IfModule prefork.c> LoadModule php5_module modules/libphp5.so </IfModule> <IfModule worker.c> LoadModule php5_module modules/libphp5-zts.so </IfModule> AddHandler php5-script .php ###################################################################### # server-status LoadModule status_module modules/mod_status.so ExtendedStatus On <Location /server-status> SetHandler server-status </Location> ##################################################################### # LoadModule dir_module modules/mod_dir.so DirectoryIndex index.php index.html ##################################################################### # #LoadModule rewrite_module modules/mod_rewrite.so #LoadModule auth_basic_module modules/mod_auth_basic.so #LoadModule authn_file_module modules/mod_authn_file.so #LoadModule authz_user_module modules/mod_authz_user.so <Directory /var/www/html> # AllowOverride FileInfo Options AuthConfig AllowOverride None Options FollowSymLinks </Directory> ##################################################################### # expiresの設定 LoadModule expires_module modules/mod_expires.so ExpiresActive On #ExpiresActive Off ExpiresByType text/css "access plus 1 day" ExpiresByType application/x-javascript "access plus 1 days" ExpiresByType application/javascript "access plus 1 days" ExpiresByType text/javascript "access plus 1 days" ExpiresByType text/plain "access plus 1 days" ExpiresByType image/gif "access plus 1 days" ExpiresByType image/jpeg "access plus 1 days" ExpiresByType image/jpg "access plus 1 days" ExpiresByType image/png "access plus 1 days" ExpiresByType image/ico "access plus 1 days" ExpiresByType image/icon "access plus 1 days" ExpiresByType text/ico "access plus 1 days" ExpiresByType application/ico "access plus 1 days" ExpiresByType image/x-icon "access plus 1 days" ##################################################################### # mod_extract_forwarded LoadModule proxy_module modules/mod_proxy.so LoadModule extract_forwarded_module modules/mod_extract_forwarded.so MEForder refuse,accept MEFrefuse all MEFaccept 127.0.0.1 MEFaddenv on MEFdebug off
以下の指摘を受けて修正しました。
最新版大切
ついでに設定反映させるのにrebootもしちゃえ
yum -y update
reboot
関連リンク
携帯とかスマートフォンでコンテンツを切り替える魔法の設定もお役に立つと思いますので是非はてなブックマークをお願いします。
最後に
こういう話出来る人が周りにすくないので是非twitterで語り合いましょう。
@s025236をフォロー
1000PV/日の稼ぎ方|まとめて2ちゃんねるの場合
先日公開した「2ch まとめサイトのまとめサイト|まとめて2ちゃんねる」が、1000PV/日↑+android版のinstall端末数が1000↑になったのでぐたぐた日記を書いてみました。
12月21日、android版公開
HTMLやCSS,JavaScriptは書けますがJavaなんて書いた事も無いので、まともに開発してたらリリースできるの数ヵ月後になってしまいます。
いろんなサイトを見ながら環境を構築して、ブラウザにまとめて2ちゃんねるのURLを渡して終了するだけというなんちゃってアプリショートカットアプリを作りました。
androidアプリはアイコンを用意するのが大変
知人にご飯ご馳走して作ってもらいましたが絵心が無いプログラマにどうしろっていうのだろうか…プログラム作成より難関でした。
1024x500 宣伝用画像(省略可能) ←アプリケーションページの頭に出てくるのでちゃんと登録したほうが良い
180x120 プロモーション画像(省略可能) ←どこで使われるのかよくわからず
512x512 高解像度アプリケーション アイコン ←marketの一覧に出るのでとても大切
??x?? スクリーンショット 2枚 ←サイズ指定がいくつかあります
72x72 高解像度アイコン
48x48 中解像度アイコン
36x36 低解像度アイコン
16x16 favicon ←自サイトに利用
なぜお金を払ってまでアンドロイドマーケットに登録をしたのか?
アンドロイドマーケットにアプリを登録するにはgoogleに開発者登録をする必要があり2,500円が必要になります。
今回の場合、アイコン作るのにご飯代もかかっています
が!
google検索で「2ch まとめ」等関連しそうなワードで検索すると星の数ほどの結果が出てきますし、ドメインエイジの壁を乗り越えることもできませんので後発のまとめて2ちゃんねるは非常に不利です。
androidマーケットのアプリ登録数は10万程度、同様のワードで検索すると200もでてきません。
これならチャンスがある!
1月2日、igoogle版公開
(igoogleなんか使ってないので)igoogle利用者ってどれくらいいるのか謎ですが、仕分けされる様子も無いのでそれなりにユーザはいるはずです。
android版を作成した再と同じ考えで、世の中に存在する2chまとめサイト数に比べればigooleガジェット登録数なんてかわいいものです。
普段から使ってる言語(HTML,CSS,JavaScript)にgadets APIを勉強すれば良いだけだったので公開してみました。
サーバ構成
サーバサイドのアプリはまったく作っておらずRSSの収集はgoogleのfeeds APIやgadgets APIまかせ
jquery等の有名なフレームワークやスクリプトは提供元のCDNまかせ
S3にコンテンツを置いてる為、アクセス数が急激に増えてもamazonが何とかしてくれるので
ユーザーの増加も安心して見てられます。
android版のインストール端末数
所で!
アンドロイドマーケットに登録するのに必要なアイコンの作成
ショートカットアプリの作成
僕のアカウントでマーケットに代行登録
のパックで1サイト○万円とかで提供したら興味ある人いませんか?
興味ある人はメールかskype等でご連絡ください。
お正月の暇つぶしに2chまとめサイトはいかがですか?
name属性にdocumentのメソッド名を指定してはいけない例
id:masa141421356:20111201:1322749788の記事が発端ではてなブックマークで話題になっていたので調べてみた。
検証コード
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.min.js"></script> <script> <!-- $(function(){ //native try { console.log( document.getElementById('target') ); }catch($e){ console.log( 'error:' + $e ); }; //jQuery try { console.log( $('#target') ); }catch($e){ console.log( 'error:' + $e ); }; }); --> </script> <style> </style> </head> <body> <form name="getElementById"></form> <div id="target">document.getElementByIdや$('#target')取得できるかな?</div> </body> </html>
結果
chromeでしか試していませんが…
思った通りgetElementByIdが使えなくなりました。
iframeでも同じ現象が発生します。
aタグ,inputタグは問題ありませんでした。
JavaScriptのArrayオブジェクトにmapメソッドとshuffleメソッドを実装する方法
当局の事情聴取に対し
等と供述していたことが判った。
ないなら実装してしまえ!
とりあえずjQueryで書いてみた
if( typeof Array.prototype.map === 'undefined') Array.prototype.map = function($_){ return jQuery.map(this,$_); }
jQuery.mapさん何してるの!?
chromeでnative版とjQuery版のベンチを取ってみたら倍ぐらい違ったのでjQueryを使わないで実装。
native版とほぼ変わらない実行速度になりました。
if( typeof Array.prototype.map === 'undefined') Array.prototype.map = function($callback){ var len = this.length; var $_ = new Array(len); for(var i =0; i<len; i++){ $_[i] = $callback.call(this,this[i],i); } return $_; };
Schwartzianで配列のシャッフルを実装
シンプルでいいですよね。(jQuery.map版は配列を返すとマージされてしまうので動きません。)
if( typeof Array.prototype.shuffle === 'undefined') Array.prototype.shuffle = function(){ return this .map(function($_){return [Math.random(),$_]}) .sort(function(a,b){return a[0] - b[0]}) .map(function($_){return $_[1]}) ; };
まとめ
array.extends.jsとか適当に名前付けて保存しとこう
/* (C) makoto@2ch.to */ if( typeof Array.prototype.map === 'undefined') Array.prototype.map = function($callback){ var len = this.length; var $_ = new Array(len); for(var i =0; i<len; i++){ $_[i] = $callback.call(this,this[i],i); } return $_; }; if( typeof Array.prototype.shuffle === 'undefined') Array.prototype.shuffle = function(){ return this .map(function($_){return [Math.random(),$_]}) .sort(function(a,b){return a[0] - b[0]}) .map(function($_){return $_[1]}) ; };