ajax跨域问题简单解决--(1)
js不能跨域请求数据,js可以跨域加载js文件,比如使用jquery可以引用官网的url,这也是跨域
解决js的跨域问题可以使用jsonp。
先来说一下什么是跨域和非跨域
简单的据一些例子
(非跨域)
http://www.123.com/index.html 调用 http://www.123.com/server.PHP
(主域名不同:123/456,跨域)
http://www.123.com/index.html 调用 http://www.456.com/server.php
(子域名不同:abc/def,跨域)
http://abc.123.com/index.html 调用 http://def.123.com/server.php
(端口不同:8080/8081,跨域)
http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php
(协议不同:http/https,跨域)
http://www.123.com/index.html 调用 https://www.123.com/server.php
请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
跨域的问题:
浏览器存在限制,不让访问数据。而不是服务端的限制,服务端正常发送请求,也正常响应了,但是当数据到达浏览器,浏览器不让js去拿这些数据。此时以上ajax的方案就起不到作用。
解决方案一:Jsonp
原理:利用 script标签,加载src路径,实现跨域加载js文件。该js文件中需要定义好一个方法,将该方法名传递给服务端,服务端根据该方法名,拼装一个方法调用语句,响应给浏览器。又浏览器来执行该语句调用方法。通过参数,将响应的数据取出即可
实现:
js:
1.定义一个方法,script加载
2.取方法中参数,进行业务处理。
jq:已经封装好了
只需要在jq的ajax中,指定dataType为"jsonp",jq在发送请求前会先定义好一个方法。 发送请求时会将该方法作为参数(callback)传递给服务端。
服务端响应,调用方法,把数据取出,传递给data,data中拿到的即为服务端数据。
服务端的配合:
改造方法:
Controller示例
//响应类型contentType可以指定produces="application/json;charset=utf-8", //也可以使用常量值 APPLICATION_JSON_UTF8_VALUE @RequestMapping(value = "/user/token/{token}",produces=MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseBody public String getUserByToken(@PathVariable String token,String callback){ E3Result result = tokenService.getUserByToken(token); //响应结果之前,要先判断是否为jsonp形式,即判断callback是否有数据 if (StringUtils.isNoneBlank(callback)) { //callback不为空,则是jsonp请求 //把结果封装成一个js语句响应 return callback + "(" + JsonUtils.objectToJson(result) + ");"; } return JsonUtils.objectToJson(result); }
Ajxa示例
1 $.ajax({ 2 3 url:"http://localhost:8080/user/token/", 4 5 dataType:"jsonp", 6 7 type : "GET", 8 9 success:function(data){ 10 11 console.log(data); 12 13 } 14 15 });
当ajax异步请求增加dataTpe:“jsonp”参数后,
1.发出去的请求类型在浏览器可以看到是script类型的,浏览器是不会校验的。普通的ajax请求是xhr类型的。
2.返回的类型不同:普通的ajax请求content-type是json,而jsonp的请求content-type是js脚本。