跨域问题及解决(1)

最近写前台请求后台数据,遇到这样的报错Origin null is not allowed by Access-Control-Allow-Origin,上网查了一下是跨域请求的问题。举个例子,如果你为你的web应用建立了一个web服务器,不过你又在这台服务器上去请求另一台服务器的数据,这种情况下跨域就会发生。跨域问题的出现本质是由于浏览器安全方面的限制,XMLHttpRequest只能访问同一域下的数据,其他的由于安全问题而拒绝访问。跨域问题分为多种情况,比如不同的域名;此外同一域名,但是不同协议,比如http和https也不可以;又比如同一个域名下,不同的端口可是不可以的。此外还有几种情况,上面的几种是比较经常会遇见的。

对于跨域访问的解决方法,网上给了几种:
1.利用 <script>标签进行解决。
不过这种方法需要和服务端那边进行配合,也就是需要在服务端编写代码来返回数据。 如果无法对服务端的代码进行修改的话这种方法是行不通的。当然,如果可以的话这种方法比proxy代理的方式要简单一些。用<script>标签进行跨域操作的原理是当浏览器请求一个js脚本的时候会同时解析并且运行脚本内的函数,从而通过服务器返回一些比如json对象数据等等。在网上找了一段样例如下:
 var scriptBlock = document.createElement("script");
 
 function StartGet() {
     scriptBlock.src = "";
     scriptBlock.src = "http://Domain2/GetData.aspx";
     scriptBlock.type = "text/javascript";
     scriptBlock.language = "javascript";
     document.getElementsByTagName("head")[0].appendChild(scriptBlock);
     scriptBlock.onreadystatechange = ReturnData;
  }
 
 function ReturnData() {
     //alert(scriptBlock.readyState);
   
     //uninitialized        Object is not initialized with data. 
     //loading            Object is loading its data. 
     //loaded            Object has finished loading its data. 
     //interactive       User can interact with the object even though it is not fully loaded. 
     //complete          Object is completely initialized. 
   
     if("loaded" == scriptBlock.readyState) {
     var div = document.getElementById("htmldiv");
      div.innerHTML = a.project[0].name; //a是返回的json里面的变量
    }    
   }
服务端的代码,从服务端的代码可见,服务端返回的是一个json的数组。
protected void Page_Load(object sender, EventArgs e)
{
   Response.Write("var a = {'project':[{'name':'a1'},{'name':'a2'}]};");
}
对于这种方法,还是那句话,需要你有能力对服务端的代码做手脚才能使用~

2.使用web代理服务器进行跨域操作。

利用在同一台服务器上的Proxy,也就是经过中间代理服务器的转发。例如域A的页面JS需要访问域B下的链接获取数据,Proxy的方法即在域A的服务器端建立一个Proxy程序(可能是PHP,ASP,servlet等任何服务端程序),域A的页面JS直接调用本域下的Proxy程序,proxy程序负责将请求发送给域B下的链接并获取到数据,最后再通过Proxy将数据返回给页面JS使用。代理转发基本的流程就如上面所说的那样,用网上的一张图看起来会更加直观一点。

使用代理proxy之后:

这种方案经过了中间Proxy,所以延迟可能稍微大一点,并且会加重本域服务器的负荷,开发工作量也稍微大一点。

雅虎开发者中心为我们提供了这样的一段代码,可以借过来参考一下:

<?php
// PHP Proxy example for Yahoo! Web services. 
// Responds to both HTTP GET and POST requests
//
// Author: Jason Levitt
// December 7th, 2005
//

// Allowed hostname (api.local and api.travel are also possible here)
define ('HOSTNAME', 'http://search.yahooapis.com/');

// Get the REST call path from the AJAX application
// Is it a POST or a GET?
$path = ($_POST['yws_path']) ? $_POST['yws_path'] : $_GET['yws_path'];
$url = HOSTNAME.$path;//获取请求完整URL

// Open the Curl session
$session = curl_init($url);//初始化一个新的会话,返回一个cURL句柄

// If it's a POST, put the POST data in the body
if ($_POST['yws_path']) {
	$postvars = '';
	while ($element = current($_POST)) {
		$postvars .= urlencode(key($_POST)).'='.urlencode($element).'&';
		next($_POST);
	}
	curl_setopt ($session, CURLOPT_POST, true);
	curl_setopt ($session, CURLOPT_POSTFIELDS, $postvars);
}

// Don't return HTTP headers. Do return the contents of the call
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);

// Make the call
$xml = curl_exec($session);

// The web service returns XML. Set the Content-Type appropriately
header("Content-Type: text/xml");

echo $xml;
curl_close($session);
?>
可以根据它的这段代码区修改然后实现自己的需要,比如我按照这个模版修改后得到了自己的代理服务器的代码。


3.
JSONP。

JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)<script>标签的src属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行。

跨域的方法还有几种,至于选择哪一种,首先要看当前面临的跨域的类别,是哪一种跨域类型,哪一种解决方法适合它,然后再根据自己的习惯来选择囖~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值