本人在初次使用PortalRest API进行开发时遇到了一些问题,折腾了几天时间,终于将开发前需要注意的一些问题理顺清楚,现将问题以及解决方法记录下来,以备日后使用。
开发目标:获取用户Token
开发环境:虚拟机Portal forArcGIS(Glassfish),本机web服务器IIS,JavaScript,HTML
遇到的主要问题有:
1、 JavaScript跨域访问
2、 HTTPS+SSL验证问题
一、JavaScript跨域访问
由于开发的web应用程序部署在本机IIS上,因此在访问虚拟机中的Porta时会存在跨域访问的问题,JavaScript出于安全方面的考虑,不允许进行这种跨域访问。解决这个问题的方式有很多,本人使用的是在web服务器端部署代理页面。ESRI提供了三种语言的代理页面代码,分别是:ASP.NET,JAVA/JSP,PHP。我们可以从下面参考链接中下载。因为使用的是IIS,所以本次开发使用ASP.NET版本代理。
代理的配置分四个步骤:
1、 下载和配置代理页面
将代理文件放到Web应用程序目录下
使用文本编辑器打开proxy.config文件,添加一个<ServerUrl>条目,URL填写Portal地址,MatchAll设置为ture(以URL开头的请求都会通过该代理)
2、 在web应用程序页面中添加代码以启用代理
在web应用程序页面的初始化功能中添加以下代码,示例如下:
3、 设置webapplication安全机制(该步骤未做深入研究,详情可以查看参考链接)
4、 测试代理是否正常工作
测试工作可以借助网络开发调试工具,如:Firebug或者Chrome的开发者工具,当我们的请求地址变为如下示例,并且请求时说明我们已经设置成功了
如果出现404错误,则表示程序无法找到proxy.ashx页面
如果出现500错误,则可以查看响应信息
二、HTTPS+SSL验证问题
上面描述的HTTP请求返回500错误,根据响应信息确定是在进行HTTPS请求过程中的远程服务器证书无效导致的,因为虚拟机中的Portal服务器没有证书,ESRI的代理访问不支持没有签名证书的访问。
这个问题有两个解决办法:
1、 通过证书颁发机构申请一个可信任的证书,如:VeriSign等
2、 绕过证书验证
第一种方法太麻烦,并且我们只是测试开发使用,所以这里选择修改porxy.ashx文件,绕过证书验证过程,使其验证结果永远为通过。
在proxy.ashx中添加以下代码:
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);并新建方法
private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }程序运行效果:
页面代码(代码修改自ESRI北京同事的Demo,在此表示感谢):
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>index</title> <script type="text/javascript"> var dojoConfig = { parseOnLoad: true }; </script> <script src="http://tm.arcgisonline.cn:8038/App1/arcgis_js_v33_api/library/3.3/jsapi/init.js" type="text/javascript"></script> <script> dojo.addOnLoad(function () { esri.config.defaults.io.proxyUrl = "proxy.ashx" }) function getToken() { var url = dojo.byId("url").value; var username = dojo.byId("username").value; var password = dojo.byId("password").value; var layersRequest = esri.request({ url: url + "/generateToken", content: { username: username, password: password, referer: "localhost", "f": "json" }, handleAs: "json", callbackParamName: "callback" }, { usePost: true }); layersRequest.then(function (response) { dojo.byId("tokenHolder").innerHTML = response.token; }, function (error) { console.log("Error: ", error); }); } </script> </head> <body> <h1 id="tokenHolder">Token is here</h1> url: <input type="text" id="url" value="https://yyx.portal.cn/sharing"/> <br/> username: <input type="text" id="username" /> <br/> password: <input type="password" id="password" /> <br/> <button onclick="getToken()"> 获取</button> </body> </html>