【问题标题】:Cross site calls without JSONP没有 JSONP 的跨站调用
【发布时间】:2013-07-25 20:41:33
【问题描述】:

我有一个使用 HTML、CSS 和 Javascript 代码构建前端的应用程序。后端将使用核心 java、Restlet 创建。

现在真正的问题是前端和后端都将在具有差异端口的差异服务器上。喜欢,前端打开:http://clientLookup(仅作为示例) 后台开启,http://lcgrke:8080

现在我将通过 Ajax 请求或 jQuery Ajax 从前端发送服务器或休息调用,然后我遇到了跨端脚本问题(SOP - 同源策略)。我不知道如何解决这个问题。

JSONP 可以是选项之一,但它仅适用于 GET 类型的调用,但在我的应用程序中,我将有 GET/POST 请求。此外,一些服务器的 url 不会启用 JSONP(不要问我为什么,只要接受它们是不可编辑的),所以 JSONP 似乎不是更好的选择。

谁能解释一下我将如何解决这个问题?

【问题讨论】:

标签: javascript gwt cross-site


【解决方案1】:

不久前我遇到了同样的问题。您可以在您的前端服务器上安装 PHP,并对该服务器上的 PHP 脚本进行 AJAX 调用。有几个用于 PHP 的 HTTP 库(cURL 是最流行的),然后您可以使用它们向后端服务器发出 HTTP 请求。基本上你可以在你的前端服务器上编写一个 PHP 脚本来充当中间人。

【讨论】:

    【解决方案2】:

    处理跨站请求的现代方式是使用CORS 而不是JSONP,但您必须了解哪些浏览器支持CORS。

    您可以在几乎现代的浏览器(IE10、FF、Chrome、Safari、Opera)上使用 CORS,但不能在 IE9/8 上使用。

    对于 IE9/8,您可以使用另一种称为 XDomainRequest 的技术,但您必须通过 JSNI 实现它。

    使用 CORS 与 JSONP 的目标是,在您的服务器端,您只需添加一个过滤器,一切都应该开箱即用(RPC、RF 等)。

    要在 gwt 中使用 CORS,您可以在有过滤器示例的 gwtquery 站点中阅读此 page。在该页面中,您还可以获得有关 jsonp 的有用信息,以及如何使用 gwtquery ajax 来简化 gwt RequestBuilder 方式。

    【讨论】:

    • 感谢您的好评。我正在浏览您提供的链接,并且能够运行跨域请求。现在我在想,如果服务器没有 Access-Control-Allow-Origin : * 怎么办,而且我无法更改它,那么在这种情况下应该怎么做?
    • 简单来说,要使用 CORS 使跨站点请求工作,服务器是否必须发送标头 Access-Control-Allow-Origin : * 或 Access-Control-Allow-Origin : ?如果服务器不响应此标头类型怎么办?
    • 在 CORS 中,客户端向服务器发出 2 个请求(OPTION 和 POST/GET/PUT...)。对于doOption 请求,服务器必须使用Access-Control-Allow-Origin Access-Control-Allow-MethodsAccess-Control-Allow-Headers 来回答(最后一个只有在您向XHR 添加任何附加标头时)。对于doPost,它只需要添加Access-Control-Allow-Origin。是的,它们是强制性的,否则客户将拒绝 XHR。
    【解决方案3】:

    如果您使用 PHP 并且有 php_culr 库可用,您可能希望利用跨源到服务器。你可以在这里看到一个例子:http://davidwalsh.name/curl-post 或者您可以使用file_get_contents 函数并序列化发布的参数,或者只传递您想要的获取参数(如果需要)。

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      Ben Alman 有一个简单的代理脚本,我用它作为这种情况的临时解决方法。

      基本上,它使用 curl 转发 GET 和 POST 请求。

      http://benalman.com/projects/php-simple-proxy/

      $url = $_GET['url'];
      $ch = curl_init( $url );
      curl_setopt($ch, CURLOPT_VERBOSE, true);
      if ( strtolower($_SERVER['REQUEST_METHOD']) == 'post' ) {
        curl_setopt( $ch, CURLOPT_POST, true );
        //curl_setopt( $ch, CURLOPT_POSTFIELDS, $_POST );
      
        $vin = $_POST["vin"];
        $subscriberProgramXML = $_POST["subscriberProgramXML"];
      
        $data = array("vin" => $vin, "subscriberProgramXML" => $subscriberProgramXML);
        $data_string = json_encode($data);
      
        $httpHeader = array('Content-Type: application/json', 'Content-Length: ' .strlen($data_string));
      
        curl_setopt( $ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
      }
      
      curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
      curl_setopt( $ch, CURLOPT_HEADER, true );
      curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
      
      curl_setopt( $ch, CURLOPT_USERAGENT, $_GET['user_agent'] ? $_GET['user_agent'] : $_SERVER['HTTP_USER_AGENT'] );
      
      
      list( $header, $contents ) = preg_split( '/([\r\n][\r\n])\\1/', curl_exec( $ch ), 2 );
      
      $status = curl_getinfo( $ch );
      
      curl_close( $ch );
      
      // Set the JSON data object contents, decoding it from JSON if possible.
      $decoded_json = json_decode( $contents );
      $data['contents'] = $decoded_json ? $decoded_json : $contents;
      
      // Generate appropriate content-type header.
      $is_xhr = strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
      header( 'Content-type: application/' . ( $is_xhr ? 'json' : 'x-javascript' ) );
      
      // Get JSONP callback.
      $jsonp_callback = $enable_jsonp && isset($_GET['callback']) ? $_GET['callback'] : null;
      
      // Generate JSON/JSONP string
      $json = json_encode( $data );
      
      print $jsonp_callback ? "$jsonp_callback($json)" : $json;
      

      该代码是从原始 php 复制粘贴的,但它只是代码的一部分。它说明了解决方案。

      【讨论】:

        【解决方案5】:

        正如@Manolo 所说,要走的路是使用 CORS(您可以在此处查看更多详细信息:http://blogs.mulesoft.org/cross-domain-rest-calls-using-cors/ - 免责声明:我写了那篇文章,但为了不让这个答案成为自我推销,您可以搜索 CORS,然后您'会找到类似的文章)。

        我可以添加到 Manolo 响应中的唯一一点是,如果您使用 jQuery,则不必担心 IE 的 XDomainRequest,因为 jQuery 会考虑那些浏览器兼容性细节。

        另外,由于您使用的是 Restlet,这篇文章会对您有所帮助:http://kodemaniak.de/2010/07/cross-domain-ajax-with-restlet-and-jquery/

        我从未使用过 Restlet,但由于它是基于 Java 的,添加 CORS 的其他简单选项是创建或使用过滤器,这是一个 Apache 许可证过滤器实现:https://bitbucket.org/thetransactioncompany/cors-filter/src

        【讨论】:

          猜你喜欢
          • 2011-10-28
          • 1970-01-01
          • 2013-07-11
          • 2012-06-25
          • 2012-05-28
          • 2015-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多