当前位置: 首页>前端>正文

RPC response exceeds rpc response exceeds maximum

用ajax访问一个service,  后端的service是用C++,CppCMS框架,作者给的例子是python写的例子利用JSON-RPC访问的方法,,需要设置Content-Type:application/json, 经测试,python可以正常访问到这个service。

新建立一个本地的html测试后,设置了xhr.setRequestHeader("Content-Type","application/json");

测试的结果是ie8 能够正常设置Content-Type, 能够和后端交互,服务器端返回status200, 获得正确结果。

但是chrome里和 ff里反复设置content-type,都不成功,在浏览器的网络面板里也没看到发出去的请求。用fiddler等工具也没有发现正确的请求头部和正确的应答结果。

在 chrome里只有设置了xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded,application/json; charset=utf-8");才能在网络面板里看到,但是被浏览器给canceled掉了. 

而且Content-Type中在把application/json放到了后边也没有请求,从这个可以发现,application/json;必须要设置为第一个参数。

调了很长都未果,后来用firebug的rest插件模拟一个请求,设置content-type:application/json, 参数"{'method':'sum','params':[1,2],'id':1}",得到正确的结果3,考虑到这些发现了是一个跨域的问题,解决了同源策略问题后,得到了正确的结果,Content-Type也正确的设置上了。

注意:IE6不支持JSON-RPC 的这种方式

简单说一下JSON-RPC 

JSON-RPC分为1.0 和 2.0

1.0的参数设置 可以参考http://json-rpc.org/wiki/specification

·        method - A String containing the nameof the method to be invoked.

·        params - An Array of objects to passas arguments to the method.

·        id - The request id. This can beof any type. It is used to match the response with the request that it isreplying to.

method:是请求的方法名

params:是一个参数数组

id:是一个唯一的id

一个例子是"{'method':'sum','params':[1,2],'id':1}";

测试代码如下:

var xhr = new XMLHttpRequest();
var params = "{'method':'sum','params':[1,2],'id':1}";
xhr.open("post", “path /rpc”, true);
xhr.setRequestHeader("Content-Type","application/json");  //要再open方法后调用
 
xhr.onreadystatechange = function() {
     if (xhr.readyState === 4) {
           if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) { 
             alert("ok") 
            }
     }
}
xhr.send(params);

Web开发由于需要经常进行ajax请求,很多时候涉及到跨域,由于浏览器的同源策略,所以会影响到正确的请求和返回数据。

关于同源策略(Same Origin Policy)

最早源于Netscape Navigator 2.0,在浏览器端是一个重要的安全策略。同源是指,域名相同,应用层协议相同,端口相同,当这些属性完全一致时时才被认为是同源。所以当遇到下面的访问时都要考虑到跨域的问题。


例如果一个页面: http://www.test.com/


父域名是test.com.

子域是

www.test.com

lab.test.com等







一些跨域的情况,当前页面是:

http://www.test.com/1/index.html



如果访问下边的页面





页面                                                        结果                                 原因



             



http://www.test.com/2/index.html          成功                            同协议 同host



http://www.test.com:82/1/other.html     失败                          不同端口80 82



https://www.test.com/1/other.html        失败



http://en.test.com/1/other.html              失败





跨域的一些方案

1 跨子域之间的相互访问

例如父域名都是test.com,子域是www.test.com 和other.test.com,

在www.test.com要通过ajax请求other.test.com页面里的一个文本other.test.com/1.txt.

这样直接请求由于是跨子域是返回不了数据的.





跨子域可以通过把两个页面都要设置domain = test.com



首先要包括子页面的一个iframe文件

<iframe src=”other.test.com/iframe.html” id=“crossIframe” ></iframe>



然后设置domain

document.domain = " test.com";





获得这个iframe的窗口,这里用jquery框架方便调用

 contentWindow是获得框架中的窗口,类似于window

var crossIframe = document.getElementById("crossIframe").contentWindow.$;
var url ="other.test.com/1.txt";
crossIframe.get(url,function(data){          
                    	alert("成功");  
                    }

                );

在other.test.com/iframe.html里要include jquery库文件

document.domain = “test.com”;

这样就可以在test.com的html页面中成功获取1.txt了







2 用注入方式跨域,经常说的jsonp

注入的主要跨域思路是建一个script脚本,append进head或者是body.



有两种方法
第一个种是在<script>标记中
例如当前的地址是www.abc.com.  要访问www.xyz.com/getResult的服务
<script src="www.xyz.com/getResult?name=hiro& &callback=?"></script>
该脚本会向www.xyz.com/getResult发送请求,该服务返回的格式要是javascript可以执行的代码,当script调用成功后,会自动调用callback.
这里需要的就是www.abc.com 里要有一个callback函数,以便刚才的script脚本成功执行后的回调。
function callback(data){

   alert(data);  //data为script脚本成功调用返回的数据

}

第二种是:

把刚才的url传入即可,动态生成一个script元素,然后插入document或者head
function JSON(url){      // 调用JSONP服务器,url为请求服务器地址

       var script =document.createElement("script");      

       script.setAttribute("type", "text/javascript");   

       script.setAttribute("src",url);

       script.setAttribute("id", url);

       document.appendChild(script);

    }





或者用jquery框架



var url = "http://www.xyz.com/getResult?name=hiro&callback=?";
$.get(url, {"targetId":targetId}, function(data){
      
},"json");



1.2版本以上只要上面写一个占位符?就可以,Jquery会把自动会把callback=?转换为注入方式







或者用jquery的$.ajax

$.ajax({  
    	type:"get",  
    	data:{},  
        url:url,  
        dataType:"jsonp",  
        jsonp:"callback",  
        success:function(data){                          
        }  
     });




3利用iframe进行两个站点的跨域

刚才所说的是跨子域的iframe方法,如果跨两个域的方法会更麻烦一些,利用iframe + location hash值进行通信。


4用后端语言作为中间层

可以用例如java c#,python等做为中间层取去请求服务,然后再返回本域的数据。


https://www.xamrdz.com/web/2uu1937509.html

相关文章: