没有JSONP的跨站点调用

Cross site calls without JSONP

本文关键字:站点 调用 JSONP 没有      更新时间:2023-09-26

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

现在真正的问题是前端和后端都将在具有不同端口的不同服务器上。比如,前端打开:http://clientLookup(仅举个例子)后端打开,http://lcgrke:8080

现在,由于我将通过Ajax请求或jQuery Ajax从前端发送服务器或rest调用,因此我遇到了跨端脚本问题(SOP-同源策略)。我不知道如何绕过这件事。

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

有人能解释一下我将如何解决这个问题吗?

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

处理跨站点请求的现代方法是使用CORS而不是JSONP,尽管您必须知道哪些浏览器支持CORS。

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

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

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

要在gwt中使用CORS,您可以在gwtquery站点中阅读此页面,那里有一个过滤器示例。在该页面中,您还有关于jsonp的有用信息,以及如何使用gwtquery-ajax,这简化了gwt-RequestBuilder的方式。

如果您使用的是PHP,并且有PHP_culr库可用,那么您可能希望利用跨原点到服务器。您可以在此处看到一个示例:http://davidwalsh.name/curl-post或者您可以使用fileget_contents函数并序列化发布的参数,或者只传递您想要的get参数(如果需要的话)。

希望这能有所帮助。

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复制粘贴的,但它只是代码的一部分。它说明了解决方案。

正如@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的另一个简单选项是创建或使用Filter,下面是一个Apache许可证筛选器实现:https://bitbucket.org/thetransactioncompany/cors-filter/src