症状
Microsoft Translator APIを使おうとしたら、タイトルどおりのエラーメッセージが出た。
APIに渡すクエリは
?text=翻訳したいテキスト&from=ja&to=en
のようになるのだが、何度ソースをみても&to=en
は間違いなく入っている。
ググると結構はまっている人がいるみたいだが、わかりやすい解決方法はみつからない。
半日以上かけてなんとか解決したので記録しておく。
原因:URLエンコードしすぎ
いろいろ確認すると、
?text=hello&from=en&to=ja
と手で入力したときにはエラーがでない。
コードを見直してみると、クエリ全体をURLエンコードしていた。
どうやらそれが原因らしく、上記のクエリのエンコードされた後の文字列を確認してみると、
%3Ftext%3Dhello%26from%3Den%26to%3Dja
みたいになっていた。
'&'や'='などもエンコードされていて、そりゃエラーがでるよね…。
URLエンコードは翻訳したいテキストだけすることにしたら解決しました。
いちおう翻訳部分だけコードを載せておきます。
アクセストークンは別に用意してください。
TypeScript
import qs = require('querystring');
// 略
translate(token, text, from_lang, to_lang, callback) {
const options = "text=" + qs.escape(text) + // ここだけエンコード
"&from=" + from_lang +
"&to=" + to_lang +
"&oncomplete=callback";
const request_options = {
host: 'api.microsofttranslator.com',
path: '/V2/Ajax.svc/Translate?' + options,
method: 'GET',
headers: {
"Authorization": 'Bearer ' + token
}
};
const req = https.request(request_options, function(res) {
var body = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
// body の中身は "callback(translated_text)" という形になっているはず。
eval(body); // callback関数に翻訳されたテキストだけ渡す。
});
});
req.on('error', function(e) {
console.log(e.message);
});
req.end();
}