JSON-RPC访问CppCMS的笔记

1 篇文章 0 订阅
1 篇文章 0 订阅

用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 的这种方式 ,setRequestHeader也不是所有浏览器都可以设置的。所以要考虑兼容性还要换其他的访问方式。

简单说一下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, https
http://en.test.com/1/other.html              失败                            不同host, 子域不同www.test.com  en.test.com

跨域的一些方案

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等做为中间层取去请求服务,然后再返回本域的数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值