【问题标题】:Post document to SOLR 4 from AngularJS从 AngularJS 将文档发布到 SOLR 4
【发布时间】:2014-04-30 00:53:00
【问题描述】:


我对此深陷兔子洞。我正在创建一个简单的应用程序,它使用 SOLR 4 作为 NoSQL 数据存储和 AngularJS v1.2.2 作为界面。我已经从命令行加载了一堆文档,AngularJS 让搜索/查看这些文档变得非常容易。我想允许文档编辑,但不能让 POST 工作。 Chrome 控制台显示 400 错误,网络选项卡显示它在 OPTIONS 方法上失败。

网络标头:
Request URL:http://localhost:8983/solr/mrm_assay/update Request Method:OPTIONS Status Code:400 Bad Request Request Headers Accept:*/* Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8,es;q=0.6 Access-Control-Request-Headers:accept, content-type Access-Control-Request-Method:POST Cache-Control:no-cache Connection:keep-alive Host:localhost:8983 Origin:http://localhost:63342 Pragma:no-cache Referer:http://localhost:63342/angular-solr2/app/index.html User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36 Response Headers Access-Control-Allow-Credentials:true Access-Control-Allow-Headers:origin, content-type, cache-control, accept, options Access-Control-Allow-Methods:GET,POST,DELETE,PUT,HEAD,OPTIONS Access-Control-Allow-Origin:http://localhost:63342 Access-Control-Max-Age:1800 Content-Type:application/xml; charset=UTF-8 Transfer-Encoding:chunked

架构概览:
SOLR 和 AngularJS 应用程序都在我的 Mac 上运行。 SOLR 使用默认的 Jetty 实例,Angular 应用程序在 WebStorm 的 IDE 的服务器内运行。 CORS 已启用,包括 GET、POST、DELETE、PUT、HEAD、OPTIONS。

更新在以下情况下起作用:

  • 使用 SOLR 的仪表板
  • 使用命令行(示例)
    $ curl http://localhost:8983/solr/mrm_assay/update -H 'Content-type:application/json' -d '[ { "keep_in_assay" {"set" : "N", "detected_endog": "N", "problems_w_is": "removed b/c requires addition post-Oasis", "onc_std_set": "set1", "fraction_id": "7", "onclistgene": "UBL3", "geneid": "UBL3_IS6", "taxonid": "9606", "peptide": "SSNVPADMINLR", "degen_human": "1", "gene_degeneracy": "1", "percnt_id": "66.7", "uuid": "6d20eb03-d3ee-4eb2-bc16-27cfaabab989" } ]'

我的 Angular 控制器代码如下所示:
assayControllers.controller('AssayUpdateController', ['$scope', '$http', function($scope, $http){ $scope.processForm = function(){ console.log($scope.assay); $http({ method:'POST', url:'http://localhost:8983/solr/mrm_assay/update', data : $scope.assay, headers : {'Content-Type': 'application/json' } }) .success(function(data, status, headers){ console.log(data.message); }) .error(function(data, status, headers, config){ console.log(status); }); }; } ]);

数据已从表单成功发送,正如我在控制台上看到的那样(尽管 JSON 对象未打包在数组中,这似乎是 SOLR 所期望的......我还尝试将 JSON 格式的数据推送到数组和 POST 但没有运气)

感谢您的帮助 - 即使只是为了指导我的故障排除!

【问题讨论】:

  • 老实说,我不知道出了什么问题,这里的一切看起来都是正确的,但作为替代方案,您是否尝试过 $http.post("localhost:8983/solr/mrm_assay/update", $scope.assay) 忽略分号 SO 是无论出于何种原因添加它
  • 是的,我也有,但也没有运气。

标签: angularjs http rest solr


【解决方案1】:

关于如何使用 AngularJS v1.2.2 将单个文档更新到 SOLR v4.7 的答案是多部分的。这仅在我的本地主机上测试过!

我。在 SOLR 附带的 Jetty 服务器上配置 CORS
solr-4.7.0/example/solr-webapp/webapp/WEB-INF/web.xml

注意事项: CrossOriginFilter 有一个参数chainPreflight,默认设置为true。这需要设置为假。 这是 CORS 转发 POST 而不是 OPTIONS 到 SOLR 的关键。。另外,顺序很重要!

<filter>
    <filter-name>cross-origin</filter-name>
    <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
    <init-param>
         <param-name>allowedOrigins</param-name>
         <param-value>http://localhost*</param-value>
    </init-param>
     <init-param>
         <param-name>allowedMethods</param-name>
         <param-value>GET,POST,DELETE,PUT,HEAD,OPTIONS</param-value>
     </init-param>
     <init-param>
         <param-name>allowedHeaders</param-name>
         <param-value>origin, content-type, cache-control, accept, options, authorization, x-requested-with</param-value>
     </init-param>
    <init-param>
        <param-name>supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>chainPreflight</param-name>
      <param-value>false</param-value>
    </init-param>
</filter>

<filter-mapping>
  <filter-name>cross-origin</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

二。 SOLR 需要数组格式的有效负载,因此您需要将 Angular 对象合并为一个。基本上,$scope.data 变成 [$scope.data]

assayControllers.controller('AssayUpdateController', ['$scope', '$http', '$location',
    function($scope,  $http, $location){
        $scope.processForm = function(){
            $http.post("http://localhost:8983/solr/mrm_assay/update?commit=true", [$scope.assay])
                .success(function(data, status, headers){
                    console.log(data.message);
                    $location.path("/assays")
                })
                .error(function(data, status, headers, config){
                    console.log(status);
                });
        };
    }
]);

三。 SOLR 文档包含 version 字段,可能会在 POST 上导致“冲突”错误。这是由于我无法追踪的缓存问题(curl 显示当前值,但浏览器有旧值;即使强制刷新)。无论如何,这对 SOLR 来说比我更有用,所以最好的办法是一开始就不要将它退还给客户。我不认为字段排除是一个选项,所以我将我想在 solrconfig.xml 中返回的所有字段列入白名单

 <!-- A request handler that returns indented JSON by default -->
  <requestHandler name="/query" class="solr.SearchHandler">
     <lst name="defaults">
       <str name="echoParams">explicit</str>
       <str name="wt">json</str>
       <str name="indent">true</str>
       <str name="df">text</str>
      <str name="fl">uuid,keep_in_assay,detected_endog,problems_w_is,onc_std_set,fraction_id,detected_by_orbi_experiments,onclistgene,geneid,taxonid,peptide,\
degen_human,degen_mouse,gene_degeneracy,department,protein_ac,pepid,protid,percnt_id,peptide_ordered</str>

现在该应用程序就像一个魅力!

【讨论】:

【解决方案2】:

如果您在 OPTIONS 请求上失败,那么就是 CORS 导致了问题。很可能是因为 Solr 附带的 jetty 不支持(或未配置)一个。 latest version of Jetty has one,不过还需要配置。

因此,您可以在 Solr 请求上禁用 CORS 或在 Jetty 中启用它。如果发布的版本不支持,升级 Jetty。

但是,您还有第二个问题。 Solr 应该直接暴露在互联网上,但应该运行在中间件客户端或 - 最坏的情况 - 一个严格限制的代理后面。否则,任何人都可以直接连接到您的实例并删除数据或造成其他损害。 Solr 甚至没有针对直接互联网访问进行安全测试。因此,在您深入“Solr-Angular”直接桥之前,请记住这一点。

【讨论】:

  • 谢谢。看起来我已经正确配置了 CORS,但你说得对,这可能是由于飞行前(也可能是 Jetty)。 SOLR 日志显示 POST 和 Content-Type 正常,然后:“CrossOriginFilter � Preflight cross-origin request to /solr/mrm_assay/update forwarded to application”。 Jetty 的 ServletHandler 调用 SolrRequestFilter,然后我立即看到“org.eclipse.jetty.server.Server � RESPONSE /solr/mrm_assay/update 400handled=true”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 2015-05-27
  • 2011-02-15
  • 1970-01-01
  • 2022-01-08
相关资源
最近更新 更多