「[JavaScript API for Office]Microsoft Translator APIを利用して選択文字列を翻訳する。」で、Microsoft Translator APIを活用した翻訳アプリについて記事を書きましたが、Word 2013 RTMで改めて確認したところ動作しなくなっていました。
OAuth認証部分で躓いているので、どうやらクロスドメイン制約に引っ掛かってしまっているようです(前回の記事を書いたときには問題なかったので、IEやOfficeのアップデートが原因?)。
対処法として「Office 用アプリの開発のベスト プラクティス」に書かれている通り、マニフェストファイルにAppDomain要素を追加してみたのですが、
複数のドメインにまたがるブラウズ
可能であれば、複数のドメインにまたがるブラウズは避けます。oAuth を使用してあるサイトのリソースを別のドメインの別のサイトと共有する場合など、これが必要なシナリオでは、アプリのマニフェスト ファイルで AppDomains 要素と AppDomain 要素を使用して指定します。
<?xml version="1.0" encoding="UTF-8"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="TaskPaneApp">
<Id>90a23a95-9db7-445c-9c71-faaccfe114bb</Id>
<Version>1.0</Version>
<ProviderName>きぬあさ</ProviderName>
<DefaultLocale>ja-JP</DefaultLocale>
<DisplayName DefaultValue="翻訳アプリ2" />
<Description DefaultValue="Microsoft Translator APIを利用して選択文字列を翻訳します。"/>
<IconUrl DefaultValue="http://officeimg.vo.msecnd.net/_layouts/images/general/office_logo.jpg" />
<AppDomains>
<AppDomain>https://datamarket.accesscontrol.windows.net</AppDomain>
<AppDomain>http://api.microsofttranslator.com</AppDomain>
</AppDomains>
<Capabilities>
<Capability Name="Document" />
<Capability Name="Workbook" />
</Capabilities>
<DefaultSettings>
<SourceLocation DefaultValue="http://localhost/apps/MSTranslator2.html" />
</DefaultSettings>
<Permissions>ReadWriteDocument</Permissions>
</OfficeApp>
結果は変わらずOAuth認証が上手くいきません。
仕方がないのでOAuth認証部分をPHPに任せることにします。
・MSTranslator.xml(マニフェストファイル)
<?xml version="1.0" encoding="UTF-8"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="TaskPaneApp">
<Id>26b8c84d-8891-4ca3-8b5f-189da663cfa7</Id>
<Version>1.0</Version>
<ProviderName>きぬあさ</ProviderName>
<DefaultLocale>ja-JP</DefaultLocale>
<DisplayName DefaultValue="翻訳アプリ" />
<Description DefaultValue="Microsoft Translator APIを利用して選択文字列を翻訳します。"/>
<IconUrl DefaultValue="http://officeimg.vo.msecnd.net/_layouts/images/general/office_logo.jpg" />
<Capabilities>
<Capability Name="Document" />
<Capability Name="Workbook" />
</Capabilities>
<AppDomains>
<AppDomain>https://datamarket.accesscontrol.windows.net</AppDomain>
<AppDomain>http://api.microsofttranslator.com</AppDomain>
</AppDomains>
<DefaultSettings>
<SourceLocation DefaultValue="http://localhost/apps/MSTranslator.html" />
</DefaultSettings>
<Permissions>ReadWriteDocument</Permissions>
</OfficeApp>
・MSTranslator.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="https://az88874.vo.msecnd.net/api/1.0/office.js"></script>
<script>
var target;
Office.initialize = function (reason) {
$(document).ready(function () {
Office.context.document.addHandlerAsync(Office.EventType.DocumentSelectionChanged, document_SelectionChange);
});
}
function document_SelectionChange(eventArgs) {
if ($("#action").attr("checked")) {
eventArgs.document.getSelectedDataAsync(Office.CoercionType.Text, function(asyncResult) {
if (asyncResult.status != Office.AsyncResultStatus.Failed) {
target = asyncResult.value;
execTranslate();
}
});
}
}
$(function(){
$("#result").click(
function() {
this.focus();
this.select();
clipboardData.setData("text", this.value);
}
);
$("#fromLng").change(function() {
if ($("#action").attr("checked")) {
execTranslate();
}
});
$("#toLng").change(function() {
if ($("#action").attr("checked")) {
execTranslate();
}
});
});
function execTranslate() {
if (target) {
fncTranslate($("#fromLng").val(), $("#toLng").val(), target);
}
}
function fncTranslate(fromLng, toLng, str) {
$("#result").val("ただいま処理中です。");
$.getJSON(
"oauth.php",
function(data, status) {
var ah = "Bearer " + data.access_token;
$.ajax({
type: "GET",
url: "http://api.microsofttranslator.com/V2/Ajax.svc/Translate",
dataType: "jsonp",
data: {
appId: ah,
text: str,
from: fromLng,
to: toLng
},
jsonp: "oncomplete",
success: function(data, dataType){
$("#result").val(data);
},
error: function() {
$("#result").val("エラーが発生しました。");
}
});
}
);
}
</script>
<style>
body {
font-family:Arial,sans-serif;
font-size:0.9em;
}
select,textarea {width:100%}
</style>
</head>
<body>
<input id="action" type="checkbox" title="チェックされている場合のみ翻訳が行われます。">動作
<table>
<tr>
<td>翻訳元言語:</td>
<td>
<select id="fromLng" title="翻訳元言語">
<option value="" selected>自動検出</option>
<option value="ar">アラビア語</option>
<option value="bg">ブルガリア語</option>
<option value="ca">カタロニア語</option>
<option value="zh-CHS">簡体字中国語</option>
<option value="zh-CHT">繁体字中国語</option>
<option value="cs">チェコ語</option>
<option value="da">デンマーク語</option>
<option value="nl">オランダ語</option>
<option value="en">英語</option>
<option value="et">エストニア語</option>
<option value="fi">フィンランド語</option>
<option value="fr">フランス語</option>
<option value="de">ドイツ語</option>
<option value="el">ギリシャ語</option>
<option value="ht">ハイチ語</option>
<option value="he">ヘブライ語</option>
<option value="hi">ヒンディー語</option>
<option value="mww">Hmong Daw</option>
<option value="hu">ハンガリー語</option>
<option value="id">インドネシア語</option>
<option value="it">イタリア語</option>
<option value="ja">日本語</option>
<option value="ko">韓国語</option>
<option value="lv">ラトビア語</option>
<option value="lt">リトアニア語</option>
<option value="no">ノルウェー語</option>
<option value="fa">ペルシャ語</option>
<option value="pl">ポーランド語</option>
<option value="pt">ポルトガル語</option>
<option value="ro">ルーマニア語</option>
<option value="ru">ロシア語</option>
<option value="sk">スロバキア語</option>
<option value="sl">スロベニア語</option>
<option value="es">スペイン語</option>
<option value="sv">スウェーデン語</option>
<option value="th">タイ語</option>
<option value="tr">トルコ語</option>
<option value="uk">ウクライナ語</option>
<option value="vi">ベトナム語</option>
</select>
</td>
</tr>
<tr>
<td>翻訳先言語:</td>
<td>
<select id="toLng" title="翻訳先言語">
<option value="ar">アラビア語</option>
<option value="bg">ブルガリア語</option>
<option value="ca">カタロニア語</option>
<option value="zh-CHS">簡体字中国語</option>
<option value="zh-CHT">繁体字中国語</option>
<option value="cs">チェコ語</option>
<option value="da">デンマーク語</option>
<option value="nl">オランダ語</option>
<option value="en" selected>英語</option>
<option value="et">エストニア語</option>
<option value="fi">フィンランド語</option>
<option value="fr">フランス語</option>
<option value="de">ドイツ語</option>
<option value="el">ギリシャ語</option>
<option value="ht">ハイチ語</option>
<option value="he">ヘブライ語</option>
<option value="hi">ヒンディー語</option>
<option value="mww">Hmong Daw</option>
<option value="hu">ハンガリー語</option>
<option value="id">インドネシア語</option>
<option value="it">イタリア語</option>
<option value="ja">日本語</option>
<option value="ko">韓国語</option>
<option value="lv">ラトビア語</option>
<option value="lt">リトアニア語</option>
<option value="no">ノルウェー語</option>
<option value="fa">ペルシャ語</option>
<option value="pl">ポーランド語</option>
<option value="pt">ポルトガル語</option>
<option value="ro">ルーマニア語</option>
<option value="ru">ロシア語</option>
<option value="sk">スロバキア語</option>
<option value="sl">スロベニア語</option>
<option value="es">スペイン語</option>
<option value="sv">スウェーデン語</option>
<option value="th">タイ語</option>
<option value="tr">トルコ語</option>
<option value="uk">ウクライナ語</option>
<option value="vi">ベトナム語</option>
</select>
</td>
</tr>
</table>
<textarea id="result" title="クリックすると内容をクリップボードにコピーします。" rows="15">ここに結果が表示されます。</textarea>
</body>
</html>
・oauth.php
<?php
//********** 要変更 **********
$client_id = "**********"; //クライアントID
$client_secret = "******"; //顧客の秘密
//****************************
$url = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
$scope = "http://api.microsofttranslator.com";
$grant_type = "client_credentials";
$ary = array (
"grant_type" => $grant_type,
"scope" => $scope,
"client_id" => $client_id,
"client_secret" => $client_secret
);
$ary = http_build_query($ary, "", "&");
$opt = array (
CURLOPT_URL => $url,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $ary,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_SSL_VERIFYPEER => FALSE
);
$ch = curl_init();
curl_setopt_array($ch, $opt);
$res = curl_exec($ch);
curl_close($ch);
//jsonとして出力
header("Content-Type: text/javascript; charset=utf-8");
print $res;
?>
今度は上手くいきました。
アプリの動作が複数のドメイン間に跨る場合は、上記のようなプロキシスクリプトの利用も有効です。


















この記事へのコメントはありません。