jQuery ajax的jsonp跨域请求
一直在听“跨域跨域”,但是什么是跨域呢?今天做了一些了解。(利用jQuery的jsonp)
jQuery使用JSONP跨域
JSONP跨域是利用script脚本允许引用不同域下的js实现的,将回调方法带入服务器,返回结果时回调。
在jQuery中内置了实现JSONP跨域的功能,如果指定为json类型,则会把获取到的数据作为一个JavaScript对象来解析,并且把构建好的对象作为结果返回。为了实现这个目的,他首先尝试使用JSON.parse()。如果浏览器不支持,则使用一个函数来构建。JSON数据是一种能很方便通过JavaScript解析的结构化数据。如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用jsonp类型。使用这种类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的URL后面。服务器端应当在JSON数据前加上回调函数名,以便完成一个有效的JSONP请求。如果要指定回调函数的参数名来取代默认的callback,可以通过设置$.ajax()的jsonp参数。
请求页面:http://10.10.0.158:8020/Test/index.html ,其中jQuery ajax URL:http://10.10.0.158:8080/newBeginning//employeeAction/showEmployeeList.do
比较即可得知他们的端口不同,需要跨域请求,否者会报
全部代码如下:
前端请求页面(index.html):
1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>jsonp</title> 7 <link rel="shortcut icon" href="img/ooopic_1482478961.ico"> 8 </head> 9 10 <body> 11 <div id="d1"> 12 <p id="p1">jsonp跨域请求</p> 13 </div> 14 </body> 15 <script type="text/javascript" src="js/jquery-1.8.3.min.js"></script> 16 <script> 17 //var iframe = document.createElement('iframe'); //动态创建框架 18 //iframe.src = "iframe.html"; //框架中加载的页面 19 //document.body.appendChild(iframe); //将框架添加到当前窗体 20 $(function() { 21 var param = new Object(); 22 param.act = "area", //表明此次请求需要跨域访问 23 24 $.ajax({ 25 type: "post", 26 url: "http://10.10.0.158:8080/newBeginning//employeeAction/showEmployeeList.do", 27 data: param, 28 dataType: "jsonp", //jsonp跨域请求 29 success: function(data) { 30 console.log("data1"); 31 console.log(data); 32 }, 33 error: function(data, type) { 34 console.log("data2"); 35 console.log(data); 36 } 37 }) 38 }) 39 </script> 40 41 </html>
后台springMVC处理跨域请求代码(employeeAction/showEmployeeList.do)
1 package com.sxdx.employee.action; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.io.UnsupportedEncodingException; 6 import java.util.HashMap; 7 import java.util.Iterator; 8 import java.util.Map; 9 import java.util.Set; 10 import java.util.Map.Entry; 11 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 15 import net.sf.json.JSON; 16 import net.sf.json.JSONArray; 17 import net.sf.json.JSONObject; 18 19 import org.springframework.stereotype.Controller; 20 import org.springframework.web.bind.annotation.RequestMapping; 21 import org.springframework.web.bind.annotation.ResponseBody; 22 23 import com.sxdx.employee.dao.employeeDao; 24 import com.sxdx.employee.domain.employee; 25 import com.sxdx.employee.service.employeeImpl; 26 27 @Controller 28 @RequestMapping(value="/employeeAction") 29 public class employeeAction { 30 @RequestMapping(value="/showEmployeeList.do") 31 public String showEmployeeList(HttpServletRequest request,HttpServletResponse response){ 32 JSONObject jsonboject=new JSONObject(); 33 JSONArray rows = new JSONArray(); 34 System.out.println(request.getParameter("pageNumber")); 35 System.out.println(request.getParameter("pageSize")); 36 employeeDao empDao=new employeeImpl(); 37 System.out.println(empDao.selectAll()); 38 for(employee emp:empDao.selectAll()){ 39 JSONObject cell = new JSONObject(); 40 cell.put("eid", emp.getEid()); 41 cell.put("ename", emp.getEname()); 42 cell.put("esex", emp.getEsex()); 43 cell.put("eage", emp.getEage()); 44 rows.add(cell); 45 } 46 //jsonboject.put("rows", rows); 47 //jsonboject.put("total", empDao.selectAll().size()); 48 49 PrintWriter out = null; 50 try { 51 response.setCharacterEncoding("UTF-8"); //设置编码格式 52 //response.setContentType("text/html"); //设置数据格式 53 String act = request.getParameter("act");//是否跨域请求,在请求时通过参数传递,以便后面判断是否需要按照跨域请求做返回 54 out = response.getWriter(); 55 if(act.equals("area")){//如果是跨域请求执行此分支 56 String callback=request.getParameter("callback");//此处即为跨域请求核心操作,获取回调方法 57 out.write(callback+"('"+rows.toString()+"')"); 58 }else{ 59 out.write(rows.toString()); 60 } 61 out.flush(); 62 } catch (IOException e) { 63 e.printStackTrace(); 64 } finally{ 65 out.close(); 66 } 67 return null; 68 } 69 }
效果:
看一些同学的博客说jsonp跨域请求不支持post方式请求,但是我试了一下,不管是$.ajax({type: "post"})还是$.ajax({type: "get"})都可以跨域请求,难道和jQuery版本有关系,不是很了解~~~请大家指教
关于这个问题已经找到原因:jsonp类型请求数据时,无法使用post方式(你会发现,在JQ中即使你将type设置为POST方式,JQ也会将其转换为get方式请求)。