没有JSONP的跨站点调用
Cross site calls without JSONP
我有一个使用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
- 如何使jQuery插件函数可调用以供独立使用,而不在集合上操作
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 当站点不是其URL的根时,如何在getJSON调用中定位API
- 从另一个站点远程调用 JavaScript 函数
- 对于Chrome扩展程序,从https站点调用http站点时出现错误
- 你能从本地脚本在另一个站点上调用 submit() 吗?
- 通过调用函数自动更新站点
- 为什么某些 API 允许跨站点 API 调用,而不允许其他 API 调用
- 没有JSONP的跨站点调用
- 对远程站点的纯JS同步AJAX调用
- 在另一个站点调用HTML表单和CSS
- 如何从Chrome扩展调用一个站点's函数
- 以一定的浏览器宽度从桌面调用移动站点
- 在加载的站点上调用Javascript
- 当调用来自iFrame时,如何获得主机站点的Http_Referrer
- Safari没有'当src不是有效的站点时,不要调用iframe-onload
- 站点不调用 AJAX,不给出错误,以前习惯这样做
- 从WordPress站点调用Valence API D2L/Brightspace API
- 如何在抛出错误时减少堆栈跟踪(点调用站点)
- 使用跨域站点但位置相同的JS文件调用子iFrame中的Javascript函数