はじめに
DeepL APIを利用した翻訳を試していました。
公式ページによると、POSTリクエストのbodyにAuth Keyと翻訳したい文章を入力する様子。
let text = "Hello, World"
let options = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'auth_key=[authKey]&text=' + text + '&target_lang=JA'
}
fetch('https://api-free.deepl.com/v2/translate', options)
.then(response => response.json())
.then(json => console.log(json.translations[0].text))
…あれ、&とか=を翻訳に含めたいときはどうすればいいんだ?
と分からなくなったのでググりました。
解決方法
encodeURIComponent()
を使えばよかったらしい。
let text = encodeURIComponent('Hello, World')
テスト
let rawText = 'hello & world'
let encondedText = encodeURIComponent(rawText)
let options = {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'auth_key=[authKey]&text=' + encondedText + '&target_lang=JA'
}
fetch('https://api-free.deepl.com/v2/translate', options)
.then(response => response.json())
.then(json => console.log(json.translations[0].text))
// => ハロー&ワールド
&が翻訳する文章として認識された。
パーセントエンコーディング
HTTPリクエストのContent-Type:application/x-www-form-urlencoded
はURLを解釈する時のルールであるらしい。
ここでは&や=はリクエスト内のname, valueペアを識別するための文字として使われる。
識別子としての意味を持たせず単なる文字列として&や=を扱いたいときは、それぞれ%26や%3Dに変換する必要がある。
この変換をパーセントエンコーディングという。
パーセントエンコーディングをJavaScriptで行うための関数がencodeURIComponent()
。
似た関数にencodeURI()
があるが、こちらはURL全体をエンコードする際に使われる。/などはエンコードされない。
今回のように、name=valueペアのnameかvalueのどちらかをエンコードする場合はencodeURLComponent()
を使う。
メモ
以下のようにURLのname=valueペアに+がある場合はスペースに変換される。
http://www.example.com/path/foo+bar/path?query+name=query+value
encodeURLComponent()
を使う限りは+は%2Bに変換されている。
直接+が入ることはないので気にしなくてもよさそう。