画竜点睛を衝く@mapyo

日々やった事をつらつらと書くブログです

euc-jpなサイトにnodeのrequestを使ってpostする時にハマって解決した事

npmのrequestを使ってeuc-jpなサイトに postするプログラムを以下のように作ろうとしていた。

CoffeeScriptです。

request = require('request')
Iconv = require('iconv').Iconv

callback = (error, response, body) ->
  if !error && response.statusCode == 200
    iconv = new Iconv('EUC-JP', 'UTF-8//TRANSLIT//IGNORE')
    contents = iconv.convert(body).toString()
    console.log contents

form =
  name: 'テストユーザー'
  memo: 'メモなのです'


request.post( {
  url: 'http://hoge.jp',
  encoding: null,
  form: form
}, callback )

と、やっていたが、postする値をeuc-jpにするところで詰まってしまった。

しかも、requestの実装を見てみると、formの値を何だかutf-8に変換しているっぽい感じだった。

https://github.com/request/request/blob/f0acc0b/request.js#L1338

たぶん、この辺。

いろいろ試行錯誤した結果、以下のようにやれば上手く行った。

  1. formはハッシュじゃなくて、文字列にする。
  2. euc-jpの文字列をurlエンコードする

サンプルは以下のような感じになる。

coffee勉強中です(言い訳

request = require('request')
Iconv = require('iconv').Iconv
Encoding = require('encoding-japanese')


urlEncodeUtf8ToEuc = (string) ->
  iconv = new Iconv('UTF-8', 'EUC-JP//TRANSLIT//IGNORE')
  string = iconv.convert(string)
  encodeString = Encoding.urlEncode(string)

callback = (error, response, body) ->
  if !error && response.statusCode == 200
    iconv = new Iconv('EUC-JP', 'UTF-8//TRANSLIT//IGNORE')
    contents = iconv.convert(body).toString()
    console.log contents

form = 'name=' + urlEncodeUtf8ToEuc('テストユーザー') + '&memo=' + urlEncodeUtf8ToEuc('メモなのです')

request.post( {
  url: 'http://hoge.jp',
  encoding: null,
  form: form
}, callback )

なんかもっと良さげな方法があったら誰か教えてください〜

参考