我目前正在使用Microsoft提供的JavaScript界面开发MS Word Office Addin。我使用Django后端进行了测试实现,其中一切正常。
但是对于最终产品,我必须将功能与现有的Java后端集成,后者运行在多个配置中,这些配置是我无法控制的。由用户界面的Vaadin组成,主要是Tomcat(但并不总是)作为Servlet容器。
我遇到了问题,即在Word中运行的IFrame会将不需要的和格式错误的_host_info附加到请求网址,其中包含非urlencoded管道字符。 例如:Tomcat Log:
"GET /myapp/?_host_Info=Word|Win32|16.01|en-US HTTP/1.1" 200 2101
此格式错误的网址会产生以下异常:
java.lang.RuntimeException: Invalid location URI received from client.
... full stack trace at bottom of the post...
Caused by: java.net.URISyntaxException: Illegal character in query at index 45: https://localhost:8443/myapp/?_host_Info=Word|Win32|16.01|en-US
据我所知,我无法控制是否将此参数附加到URL,因为在Addin的Manifest文件中我只指定了如下所示的源URL,并且信息会自动添加。
<SourceLocation DefaultValue="https://localhost:8443/myapp/ " />
检查Documentation我在那里找不到这种行为,所以我可能会遗漏一些东西。 this博客文章中提到了查询主机信息,但它似乎不应该是URL的一部分。
有没有办法可以阻止Office加载项附加: 请求?_ host_Info = Word | Win32 | 16.01 | zh-CN HTTP / 1.1 ?
如果没有,是否有正确的方法来使用Tomcat过滤/忽略该部分URL?由于整个应用程序已经使用我的Apache Webserver&amp; Django Backend,也收到了URL,但它有效。
至于问题二,我已经尝试实现一个应该删除相关参数的Servlet过滤器。但由于它依赖于相同的Java库来解析URL以查看它,因此抛出相同的异常。
> May 23, 2016 11:04:51 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [MyUIServlet] in context with path [/word-to-moxis] threw exception [com.vaadin.server.ServiceException: java.lang.RuntimeException: Invalid location URI received from client] with root cause
java.net.URISyntaxException: Illegal character in query at index h(invalidated link because of 10 reputation / two links allowed policy)ttps://localhost:8443/myapp/?_host_Info=Word|Win32|16.01|en-US
at java.net.URI$Parser.fail(URI.java:2848)
at java.net.URI$Parser.checkChars(URI.java:3021)
at java.net.URI$Parser.parseHierarchical(URI.java:3111)
at java.net.URI$Parser.parse(URI.java:3053)
at java.net.URI.<init>(URI.java:588)
at com.vaadin.server.Page.init(Page.java:651)
at com.vaadin.ui.UI.doInit(UI.java:679)
at com.vaadin.server.communication.`UIInitHandler`.getBrowserDetailsUI(UIInitHandler.java:214)
更新
以下快速&amp; Dirty Hack可以解决问题。仍然感到困惑的是他们为什么选择以这种方式编码信息:
public class AddinServletRequestWrapper extends HttpServletRequestWrapper {
Map<String, String[]> parameterMap;
public AddinServletRequestWrapper(HttpServletRequest originalRequest) {
super(originalRequest);
parameterMap = new HashMap<String, String[]>(originalRequest.getParameterMap());
parameterMap.remove("_host_Info");
}
@Override
public String getParameter(String name) {
// TODO: Improve
String[] value = parameterMap.get(name);
if (value == null || value.length == 0)
return null;
if(name == "v-loc"){
return value[0].replace('|', '_');
}
return value[0];
}
}
Update 2 / Feb17:
使用最新的Tomcat更新,上面的解决方法不再足够。如评论中所述,版本 7.0.73 , 8.0.39 , 8.5.7 具有更严格的网址政策。因此,没有解决方案可以使用tomcat版本来托管办公室加载项而无需额外的工具。我真的希望这种情况很快就会发生变化,因为这样一个很小的,可能没用的字符串可以在部署中使用这些问题。
答案 0 :(得分:4)
更新: API现在可供使用:
的console.log(Office.context.host); //示例:Excel
的console.log(Office.context.platform); //示例:PC,MAC,IOS,null(对于独立网站)
主机的可能值为: 字 高强 微软幻灯片软件 外表 OneNote中 项目 访问
平台的可能值是: 个人计算机 OfficeOnline 苹果电脑 iOS版 Android的 通用
我们最近根据单页面应用程序中提到的问题从URL中删除了查询参数。对于在浏览器中打开的加载项(Office Online),不再附加_host_info_。
@Matthias:对于此问题,添加office-js
标记会更准确。鉴于标签的大小限制,我无法追加。
答案 1 :(得分:2)
如果你的tomcat前面有一个启用了mod_rewrite的apache,可以添加这个脏的apache规则来重新编码outlook请求:
RewriteCond %{QUERY_STRING} (.*)_host_Info=(.*)\|(.*)\|(.*)\|(.*)\|(.*)\|(.*) RewriteRule ^(.*) "$1?%1_host_Info=%2\%7c%3\%7c%4\%7c%5\%7c%6\%7c%7" [QSD,PT]
我希望这可以提供帮助
答案 2 :(得分:1)
如果你正在使用urlRouteProvider,这个URL的更改也会在Angular中造成严重破坏。它似乎创建了一个摘要循环,因为它是在Angular内部触发的位置更改事件,超过了摘要的10循环限制。 :(
答案 3 :(得分:0)