这两天用Ajax连接后端JSON-RPC的服务, 后端的service是用C++写的,用到的是cppcms,作者给的例子是python写的,需要设置Content- Type:application/json,经测试,python可以正常访问到这个service。
后端由于已经限定了Content-Type, 考虑到需要和其他服务器端通信也需要到这个设置,不好做出修改。所以在浏览器端也要进行该设置,在查阅了资料后,发现请求头的类型可以自己任意设置,例如 setRequestHeader(name,value);
新建了一个本地的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也正确的设置上了。
开始时由于没有正确的设置上Content-Type,思路限定在Content-Type值的设置方法上了,例如HTTP请求一些设置依赖关系, 例如是否要同时设置上Accept,Content-length等。 最后才发现是同源策略影响到了setRequestHeader正确的设置。
简单说一下JSON-RPC
JSON-RPC 分为1.0 和2.0
1.0的参数设置 可以参考http://json-rpc.org/wiki/specification
- · method – AString containing the name of the method to be invoked.
- · params – AnArray of objects to pass as arguments to the method.
- · id – The request id. This can be of anytype. It is used to match the response with the request that it is replying to.
method:是请求的方法名
params:是一个参数数组
id:是一个唯一的id
一个例子是“{‘method’:’sum’,’params’:[1,2],’id’:1}”;
2.0多加了一个版本号 参考 http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal
{“jsonrpc”: “2.0″, “method”:”subtract”, “params”: [42, 23], “id”: 1}
在项目中用到的是1.0的格式
测试代码如下
1
2
3
4
5
6
7
8
9
10
11
12
|
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)
|
如果用jquery调用更简单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
$.ajax({
url: “/rpc",
type:
"post"
,
dataType:
"json"
,
data:
'{"method":"sum","params":[1,2],"id":1}'
,
contentType:
"application/json; charset=utf-8"
,
beforeSend: function(x) {
//这个不需要设置,要不可能在有得浏览器中出现重复的content-type
//x.setRequestHeader("Content-Type", "application/json;charset=utf-8");
},
success: function(json) {
alert(
"ok"
);
},
error: function(x, e) {
alert(
"error"
);
},
complete: function(x) {
alert(
"complete"
);
}
})
|
Web开发由于需要经常进行ajax请求,很多时候涉及到跨域,由于浏览器的同源策略,所以会影响到正确的请求和返回数据。
关于同源策略(Same Origin Policy)
最早源于NetscapeNavigator
2.0,在浏览器端是一个重要的安全策略。同源是指,域名相同,应用层协议相同,端口相同,当这些属性完全一致时时才被认为是同源。所以当遇到下面的访问时都要考虑到跨域的问题。
说明:
http://www.test.com/
父域名是test.com.
子域是
www.test.com
lab.test.com等
举一个例子
假如当前页面是
http://www.test.com/1/index.html
比较的url | 结果 | 原因 |
http://www.test.com/1/index.html
http://www.test.com/1/index.html |
成功 | 同协议同host |
http://www.test.com/1/index.html
http://www.test.com/2/index.html |
成功 | 同协议同host 不同文件夹 |
http://www.test.com/1/index.html
http://www.test.com:82/1/other.html |
失败 | 不同端口 80和82 |
http://www.test.com/1/index.html
https://www.test.com/1/other.html |
失败 | 不同协议 http — https |
http://www.test.com/1/index.html
http://en.test.com/1/other.html |
失败 | 不同host(子域不同) www —en |
http://www.test.com/1/index.html
http://test.com/1/other.html |
失败 | 不同host www—test |
http://www.test.com/1/index.html
http://other.www.test.com/dir/other.html |
失败 | 不同host www—other.www |
跨域的一些方案
1 跨子域之间的相互访问
例如父域名都是test.com,子域是www.test.com 和other.test.com,
例如在www.test.com要通过ajax请求other.test.com页面里的一个txt页面other.test.com/1.txt.这样由于是跨域是不能得到的.
不过这个问题是跨子域,可以通过把两个页面都要设置domain = test.com”。
在主页面
test.com的html里
首先要包括子页面的一个html文件
然后设置domain
document.domain = “ test.com”;
获得这个iframe的窗口,这里用jquery框架方便调用
contentWindow是获得框架中的窗口,类似于window
1
|
var
crossIframe = document.getElementById(‘ crossIframe ‘).contentWindow.$;
|
2
|
crossIframe.get(“http:
//other.test.com/1.txt”,function(data){
|
3
|
alert(“成功“);
|
4
|
});
|
5
|
}
|
在other.test.com/iframe.html里要include jquery库文件
同样也要也要设置
document.domain = “test.com”;
这样就可以在test.com的html页面中成功获取1.txt了
2 用注入方式跨域,经常说的jsonp
注入的主要跨域思路是建一个script脚本,append进head或者是body.
有两种方法
第一个种是在
该脚本会向www.xxxxx.com/getResult
发送请求,该服务返回的格式要是javascript可以执行的代码,当script调用成功后,会自动调用callback.
这里需要的就是www.abc.com
里要有一个callback函数,以便刚才的script脚本成功执行后的回调。
function callback(data){
alert(data); //data为script脚本成功调用返回的数据
}
动态注入的方法:
把刚才的url传入即可,动态生成一个script元素,然后插入document或者head
1
|
function
JSON(url){
// 调用JSONP服务器,url为请求服务器地址
|
2
|
var
script =document.createElement(“script”);
|
3
|
script.setAttribute(“type”,”text/javascript”);
|
4
|
script.setAttribute(“src”,url);
|
5
|
script.setAttribute(“id”,url);
|
6
|
document.appendChild(script);
|
7
|
}
|
如果利用jquery会更方便些
例如
1
|
Var url = “<a href=
"http://www.xyz.com/getResult
"
>www.xyz.com/getResult</a>?callback=?”;
|
2
|
$.get(url, {“name”:”hiro”},
function
(data){ },”json”);
|
1.2版本以上只要上面写一个占位符?就可以,Jquery会把自动会把callback=?转换为注入方式
或者用jquery的$.ajax
1
|
$.ajax({
|
2
|
type:“get”,
|
3
|
data:{},
|
4
|
url:url,
|
5
|
dataType:“jsonp”,
|
6
|
jsonp:“callback”,
|
7
|
success:
function
(data){}
|
8
|
});<strong></strong>
|
3利用iframe进行两个站点的跨域
刚才所说的是跨子域的iframe方法,如果跨两个域的方法会更麻烦一些,利用iframe + location hash值进行通信。
4用后端语言作为中间层
在本域下,由于服务器端语言没有跨域的限制,所以可以用例如java c#,python等去请求服务,然后再返回本域的数据。
相关推荐
JQuery的跨域解决方案主要依赖于JSONP(JSON with Padding)技术。JSONP是一种绕过同源策略的方式,它利用HTML中的`<script>`标签没有同源策略限制的特点。当jQuery使用`dataType: 'jsonp'`时,它实际上是在做以下几...
【AJAX跨域解决办法】 在Web开发中,AJAX(Asynchronous JavaScript and XML)是一种在无需刷新整个页面的情况下更新部分网页的技术。然而,由于浏览器的同源策略限制,AJAX请求通常只能发送到与当前页面同一源的...
为了解决跨域问题,PDF.js 提供了几种解决方案: 1. 服务器端配置:在服务器端设置 CORS 头部,允许来自其他域的请求。例如,在 Apache 或 Nginx 配置中添加 `Access-Control-Allow-Origin` 头,指定允许访问的源...
ssm跨域问题解决方案
### Tomcat跨域解决方案 #### 一、背景与问题描述 在现代Web开发中,由于浏览器的安全策略限制,不同源之间的资源访问会受到限制,这种现象被称为“同源策略”(Same-Origin Policy)。同源策略是为了保护用户数据...
解决arcgis server跨域问题: 1、停掉ArcGIS Server的服务。 2、 打开<ArcGIS Server> \framework\runtime\tomcat\conf\web.xml,注册跨域bean 3、lib下拷贝 cors-filter-2.5.jar java-property-utils-1.9.1.jar包 4...
为了解决这个问题,MVC框架提供了多种策略和配置,允许我们实现跨域请求。在这个案例中,我们将详细探讨如何在MVC中设置跨域。 1. CORS(Cross-Origin Resource Sharing,跨源资源共享):这是解决跨域问题的主要...
**Ajax跨域访问解决方案** 在Web开发中,Ajax(Asynchronous JavaScript and XML)技术被广泛用于实现页面的异步更新,提升用户体验。然而,由于浏览器的同源策略限制,Ajax请求只能向同源(协议、域名和端口相同)...
### 跨域访问解决方案与Cookie处理 在现代Web开发中,跨域问题一直是困扰开发者的一大难题。当浏览器出于安全考虑阻止不同源之间的数据交互时,跨域问题便产生了。为了解决这一问题,并确保在跨域场景下可以正确地...
【标题】:“Tomcat配置解决跨域问题” 在Web开发中,跨域(Cross-Origin)是一种常见的安全限制,它阻止浏览器从一个源加载资源到另一个不同的源。这主要是为了防止恶意脚本通过注入来窃取数据。然而,在进行前后...
总结起来,SignalR 跨域问题的解决方案主要依赖于 CORS 配置,同时可以结合其他技术如 JSONP、代理服务器、IFrame 和 PostMessage,以及 WebSocket 协议,根据实际项目需求选择合适的解决方案。正确配置后,SignalR ...
本文将深入探讨JS跨域的解决方案,帮助开发者理解并解决这个问题。 首先,我们需要了解什么是同源策略。同源策略是浏览器为了保护用户数据安全而实施的一项机制,它限制了来自不同源的脚本之间进行交互。然而,这在...
本篇文章将详细介绍如何解决Geoserver的跨域问题。 首先,我们需要理解跨域问题的背景。根据同源策略,浏览器只允许与同一源(协议+域名+端口)的请求进行通信。但在实际应用中,比如一个网站前端和Geoserver不在同...
JavaScript跨域访问解决方案 在Web开发中,由于浏览器的安全策略——同源策略(Same Origin Policy),不同源的脚本之间无法直接通信或访问彼此的资源。同源策略规定,只有当两个URL的协议、域名和端口都相同时,...
标题和描述所提及的是一个关于如何解决layer弹窗在跨域环境下的问题,主要涉及到iframe、跨域以及layer的使用技巧。下面我们将详细探讨这个问题及其解决方案。 首先,我们了解下**iframe**。iframe(Inline Frame)...
本文将深入探讨如何“完美解决iframe跨域问题”,并介绍其底层的`window.name`转换代理实现。 **一、iframe跨域的基本概念** 1. **什么是iframe**:iframe是一种HTML元素,允许在单个网页中嵌入另一个网页。它通过...
springboot跨域 springboot解决跨域问题+不同版本springboot解决跨域问题
### ASP.NET跨域SSO解决方案 #### 一、引言 在现代企业级应用开发中,随着业务系统越来越复杂,各个子系统之间的交互也日益频繁。为了提高用户体验并简化管理流程,单点登录(Single Sign-On,简称SSO)成为了一个...
ajax跨域问题的解决办法 ajax跨域问题是指在使用ajax技术时遇到的跨域限制问题,即ajax请求不能跨域访问其他域的服务器资源。这种限制是由于浏览器的同源策略所引起的,同源策略规定一个域下的脚本只能访问该域下的...
### iframe跨域通信解决方法 在现代Web开发中,跨域问题经常出现并困扰着开发者。尤其是在使用`iframe`嵌入不同源的内容时,主页面往往无法直接与`iframe`内的内容进行交互,这就需要一种解决方案来实现跨文档消息...