読者です 読者をやめる 読者になる 読者になる

はかますたいる!きょろの技的雑記

井上恭輔(@kyoro353)の私的かつ技的な日記です。米国サンフランシスコで暮らすエンジニアです。

Titanium+RailsでHTTP通信するときに、デフォルトのままではUserAgentの問題にぶつかる

わお!もう1年近くはてな書いてなかったのか!と驚愕しつつ、
これからは余り気張らず、ちょくちょくメモ程度の軽い気持ちで書くことしようと思いました。
アウトプット重要。この1年は本当に色々あったなぁ。その話は後日。

      • -

本題。TitaniumからRailsで書いたAPIエンドポイントと通信しようと思って地味にはまった。
バージョンの関係もあるのだけど、現行版のTitaniumではTitanium.Network.createHTTPClient()が
デフォルトではUserAgentがセットされない(空っぽ)みたい。
で、UAが未設定だと、Railsで無条件に500を返して弾いちゃう。
ブラウザからAPIに同じリクエストを送っても何も問題なく表示されるので最初はわからなかった。

UsaAgent見設定だと、こんな感じになる。

Started GET "/count" for 67.188.150.120 at 2011-11-19 17:54:54 +0900
  Processing by CallbackController#count as 
Completed 500 Internal Server Error in 57ms

NoMethodError (undefined method `ref' for nil:NilClass):

で、これに対処するためにTitanium側では何らかのUAを設定してあげる。

var xhr = Ti.Network.createHTTPClient();
 
xhr.open('GET', 'http://www.example.com');
xhr.setRequestHeader('User-Agent','Titanium);
 
xhr.onload = function(e){
    // do something here
}
xhr.send();

さらに、Rails側は下記のページ参考にしてBeforeFilterでMimeTypeを設定してあげる。
めんどくさいときはApplicationコントローラでやってもいいと思う。

GET request with params in Titanium to a Rails backend
http://ariera.github.com/2011/08/30/get-request-with-params-in-titanium-to-a-rails-backend.html

    # config/initializers/mime_types.rb
    Mime::Type.register_alias "text/html", :titanium

    # app/controllers/application_controller.rb
    before_filter :handle_titanium
    
    def titanium_user_agent?
      @mobile_user_agent ||= ( request.env["HTTP_USER_AGENT"] && 
        request.env["HTTP_USER_AGENT"][/Titanium/] )
    end
    
    def handle_titanium
      request.format = :titanium if titanium_user_agent?
    end

これで問題なくRailsと通信できるよ。

enjoy !