介绍
JSONP是一直种解决跨域问题的方案,实现的原理来自于页面中的<script>
标签能够跨域请求资源。要通过JSONP实现跨域,需要服务器端做额外支持。
前端代码
前端部分核心在于通过script标签的src告诉服务器端约定好的回调方法名
。代码如下
var callbackName = 'callbackFunc';
window[callbackName] = function (response) {
// 对返回的数据做后续处理
console.log(response)
};
var script = document.createElement('script');
script.src = 'http://127.0.0.1:8080/sword-room/JSONPServlet?callback='+callbackName+'¶m=JSONP';
document.body.appendChild(script);
后端代码
服务端部分主要为接收前端发送过来的请求参数,核心在于约定好的方法名
。代码如下
package com.demo;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/JSONPServlet")
public class JSONPServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public JSONPServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//请求参数
String param = request.getParameter("param");
//跟前端部分约定好的方法名
String callback = request.getParameter("callback");
PrintWriter out = response.getWriter();
//返回JSON字符串
response.setContentType("text/javascript; charset=UTF-8");
String jsonData = "{a:1,b:2,param:'"+param+"'}";
out.print(callback+"("+jsonData+");");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
结果
下图为验证结果:
其它
1.前台部分jquery对jsonp的支持,只需设置dataType:"jsonp"
,样例如下
$.ajax({
url:"http://127.0.0.1:8080",
dataType:"jsonp",
data:{
userName:'管理员'
},
success:function(data){
console.log(data)
}
});
2.后台Java部分可使用fastjson来实现返回数据
JSONPObject OBJ = new JSONPObject();
//jquery ajax jsonp默认的方法参数名为callback,可使用jsonpCallback:'newcallback'自定义
OBJ.setFunction(request.getParameter("callback"));
//设置返回数据
OBJ.addParameter(result);
this.writeToPage(response, OBJ);
3.跨域情况下一般都牵涉到权限问题,可通过SSO或者服务器端开放匿名访问权限解决,或者token也行
4.使用Nginx的代理功能来解决跨域问题也是很好的一种办法