什么是跨域?怎么解决跨域问题?

什么是跨域?

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。

所谓同源是指,域名,协议,端口均相同,不明白没关系,举个栗子:

http://www.123.com/index.html 调用 http://www.123.com/server.php (非跨域)

http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)

http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)

http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)

http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。

解决办法:

1、JSONP:

使用方式就不赘述了,但是要注意JSONP只支持GET请求,不支持POST请求。

2、代理:

例如www.123.com/index.html需要调用www.456.com/server.php,可以写一个接口www.123.com/server.php,由这个接口在后端去调用www.456.com/server.php并拿到返回值,然后再返回给index.html,这就是一个代理的模式。相当于绕过了浏览器端,自然就不存在跨域问题。

3、PHP端修改header(XHR2方式)

在php接口脚本中加入以下两句即可:

header('Access-Control-Allow-Origin:*');//允许所有来源访问

header('Access-Control-Allow-Method:POST,GET');//允许访问的方式



json和jsonp的使用区别

一.    跨域请求的概念

  JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。

 

二.    json和jsonp

  JSON是一种基于文本的数据交换方式(不支持跨域),而JSONP是一种非官方跨域数据交互协议。

  使用json格式传递数据的客户端代码如下:

复制代码
 1 $(function () {
 2     var user = {
 3         "username": "HelloWorld"
 4     };
 5 
 6     $.ajax({
 7         url: "http://localhost:8080/Changyou/UserInfo",
 8         type: "POST",
 9         contentType: "application/json; charset=utf-8",
10         dataType: "json",  //json不支持跨域请求,只能使用jsonp
11         data: {
12             user: JSON.stringify(user)
13         },
14         success: function (data) {
15             $("#user_name")[0].innerHTML = data.user_name;
16             $("#user_teleNum")[0].innerHTML = data.user_teleNum;
17             $("#user_ID")[0].innerHTML = data.user_ID;
18         },
19         error: function () {
20             alert("请求超时错误!");
21         }
22     })
23 });
复制代码

  然而,简单地使用json并不能支持跨域资源请求,为了解决这个问题,需要采用jsonp数据交互协议。众所周知,js文件的调用不受跨域与否的限制,因此如果想通过纯web端跨域访问数据,只能在远程服务器上设法将json数据封装进js格式的文件中,供客户端调用和进一步处理,这就是jsonp协议的原理。该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

  简单的说,就是json不支持跨域,而js可以跨域,因此在服务器端用客户端提供的js函数名将json数据封装起来,再将函数提供给客户端调用,从而获得json数据。

  开发过程中,如果出现类似 “Origin ****** is not allowed by Access-Control-Allow-Origin.” 的错误,则可能是由于json数据不支持跨域导致的,应考虑使用jsonp协议。

  如果出现类似 ”SyntaxError: Unexpected token ':'. Parse error.“ 的错误,则可能是由于返回的json数据没有用”callback“传递的函数名封装导致的。

  客户端代码如下:

复制代码
 1 $(function () {
 2 
 3     var user = {
 4         "username": "HelloWorld"
 5     };
 6 
 7     $.ajax({
 8         url: "http://localhost:8080/Changyou/UserInfo",
 9         type: "POST",
10         contentType: "application/json; charset=utf-8",
11         dataType: "jsonp",  //json不支持跨域请求,只能使用jsonp
12         data: {
13             user: JSON.stringify(user)
14         },
15         jsonp: "callback",  //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名,默认为callback
16         jsonpCallback: "userHandler",  //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
17         success: function (data) {
18             $("#user_name")[0].innerHTML = data.user_name;
19             $("#user_teleNum")[0].innerHTML = data.user_teleNum;
20             $("#user_ID")[0].innerHTML = data.user_ID;
21         },
22         error: function () {
23             alert("请求超时错误!");
24         }
25     })
26 });
复制代码

   服务器端代码如下:

复制代码
 1 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2     response.setContentType("application/json; charset=utf-8");
 3     String username = new String(request.getParameter("user").getBytes("ISO-8859-1"),"utf-8");
 4     String callback = new String(request.getParameter("callback").getBytes("ISO-8859-1"),"utf-8");
 5     System.out.println("接收到的数据:" + username);
 6     System.out.println("callback的值:" + callback);
 7     JSONObject user = JSONObject.fromObject(username);
 8     System.out.println("接收到的用户名:" + user.get("username"));
 9     JSONObject userinfo = new JSONObject();
10     userinfo.put("user_name", "张鸣晓");
11     userinfo.put("user_teleNum", "18810011111");
12     userinfo.put("user_ID", "123456789098765432");
13     PrintWriter out = response.getWriter();
14     String backInfo = callback + "(" + userinfo.toString() + ")"; //将json数据封装在callback函数中提供给客户端
15     out.print(backInfo);
16     out.close();
17 }
复制代码

 

尽管客户端没有实现userHandler函数,但也能成功运行,原因就是jquery在处理jsonp类型的ajax时,自动帮你生成回调函数并把数据取出来供success属性方法来调用。

 

更详细解释,参见http://kb.cnblogs.com/page/139725/








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值