jquery Ajax跨域调用

来源:互联网 发布:释放被占用的端口 编辑:程序博客网 时间:2024/05/21 06:21

        最近项目中要使用跨域调用,所以开始研究,虽然简单,中间却也出现不少问题。至于jsonp和跨域的介绍,网上到处都是,此处就不再赘述,有需要的自行查找吧,本文就在直接进入应用了。
ps:跨域需使用两个不同的服务,可以w3c的在线测试作为请求端,自己的服务作为服务端,w3c的在线测试工具,可以通过任意一个“亲自试一试”进入哦。

一. 前台代码

本文前台有两种写法,但是大同小异,不过是远程要不要写js的问题,仅供参考。

   1. 不调用远程js

<html><head><script type="text/javascript" src="/jquery/jquery.js"></script><script type="text/javascript">function demo(name){$.ajax({url : "http://..地址.../Demo/jsonpServlet.do", data : {"name" : name},dataType : "jsonp",//jsonp: "callback",//jsonpCallback: "callbackFun",  success : function(data) {alert(data.msg);},error : function(XMLHttpRequest,error,exp) {alert("XMLHttpRequest:"+XMLHttpRequest.status+"\nerr:"+error+"\n exp:"+exp);}   //error用于提示错误信息,可不用});}</script></head><body><input type="button" value="click" onclick="demo('aaa');"/></body></html>
关于jsonp和jsonpCallback两个参数,在ajax发送请求时,会被发送给服务器,如果不写,jquery会自动生成,jsonp默认为callback,而jsonpCallback随机生成,如不明白,可再参考本文后台代码部分,以下是w3c原文:

jsonp

在一个 jsonp 请求中重写回调函数的名字。这个值用来替代在 "callback=?" 这种 GET 或 POST 请求中 URL 参数里的 "callback" 部分,比如 {jsonp:'onJsonPLoad'} 会导致将 "onJsonPLoad=?" 传给服务器。

jsonpCallback

为 jsonp 请求指定一个回调函数名。这个值将用来取代 jQuery 自动生成的随机函数名。这主要用来让 jQuery 生成度独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。


2.使用远程js

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>index</title><script type="text/javascript" src="js/jquery-1.9.1.js"></script><script src="http://--远程地址--/Demo/js/remote.js"></script></head><body><script>function getData(data){alert(data);}function test(){demo("admin",getData);}</script><input type="button" value="click" onclick="test();"/></body></html>


此方法写一个remote.js,而此js文件有服务端提供。

function demo(name,callbackFun){$.ajax({url : "http://--地址--/Demo/jsonpServlet.do",data : {"name" : name},dataType : "jsonp",success : function(data) {callbackFun(data);},error : function(XMLHttpRequest,error,exp) {alert("XMLHttpRequest:"+XMLHttpRequest.status+"\nerr:"+error+"\n exp:"+exp);}});}

这种方法相对前一种,不过是多传递了函数,这样写的好处是调用端只需要使用数据就可以了,不需要知道服务提供数据的url($.ajax的url部分),服务端可以随意改动服务。


二、服务端后台代码

一个非常简单的servlet
package com.demo;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class JsonpServlet extends HttpServlet{    private static final long serialVersionUID = 1L;    @Override    public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=UTF-8");String callback = req.getParameter("callback"); //引号中的callback就是上面提到的jsonp默认的参数传递名,通过它可取的回调函数,//即jsonpCallback部分,        String name = req.getParameter("name");        System.out.println("name = "+name+"\tcallback = "+callback);        String msg = null;        if (name.equals("admin")) {            msg = "it is right!";        }else {            msg = "Sorry,it is wrong!";        }        msg = "{'msg':'"+msg+"'}";   //组装json数据        resp.getWriter().write(callback.concat("(").concat(msg).concat(")")); //组装输出格式        resp.getWriter().flush();    }    @Override    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        this.doPost(req, resp);    }}


注意:
1.callback.concat("(").concat(msg).concat(")")是组装返回数据的格式,注意一定要组装为这种 “ 回调函数(json数据)”的格式,若只输出json数据,而没有外面的回调函数,会得到parseerror的错误和xxx was not called的异常

2. json中不要有引号等符号,这同样会造成上面的错误。本人就犯了此错误,浪费了大量时间o(╯□╰)o.......