CORS 使用ajax+servlet实现

前端之家收集整理的这篇文章主要介绍了CORS 使用ajax+servlet实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

主要是针对非IE的CORS实现,因为IE的CORS直接使用XDomainRequest,比较简单,功能也比较简单。在此是针对非IE中如何实现跨源。

主要有两个方面:1.如何使用PreflightRequest实现功能较丰富跨域请求,功能丰富体现在:可以发送自定义头部信息;可以使用get和post以外的方法;可以发送不同类型的主体内容。摘录一段文档:

Unlike simple requests(discussed above),"preflighted" requests first send an HTTP request by the@H_502_8@OPTIONSmethod to the resource on the other domain,in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular,a request is preflighted if:

(1)It uses methodsotherthanGET,HEADorPOST. Also,ifis used to send request data with a Content-Typeapplication/x-www-form-urlencoded,multipart/form-datatext/plainrequest sends an XML payload to the server usingapplication/xmltext/xmlispreflighted.
(2)It sets custom headers in the request (e.g. the request uses a header such asx-zd)

Note:Starting inGecko2.0,thetext/plain,application/x-www-form-urlencoded,andmultipart/form-datadata encodings can all be sent cross-site without preflighting. PrevIoUsly,onlytext/plaincould be sent without preflighting.


(参考资料:https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control

源码实例:js部分:

function crosFunc(){
		var xhr=new XMLHttpRequest();
		xhr.onreadystatechange=function(){
			if(xhr.readyState==4){
				if(xhr.status>=200&&xhr.status<=300||xhr.status==304){
				console.log("--->"+xhr.getAllResponseHeaders());//为空,不能访问返回的头信息
					console.log(xhr.responseText);
					console.log(console.log(document.cookie));//username=444  undefined  因为同源策略的影响,访问不到从服务器返回来的cookie
				}
				else{
					alert("cros Failed!");
				}

			}
		}
				if('withCredentials' in xhr){//检测xhr是否支持CORS,如果不支持,说明是ie,就只能使用XDomainRequest进行跨域
				console.log("it is true");
				}
		xhr.open('get','http://202.197.66.228:8083/TestCORS/ServerServlet',true);	
	        xhr.setRequestHeader('x-zd','zd');//发送自定义头部	
		xhr.send(null);		
	}
crosFunc();
</script>
servlet部分:注意红色部分的代码,要在doOptions中加入一些头信息,这样浏览器才会把结果交给js,否则就会出错
public class ServerServlet extends HttpServlet {

	
	public ServerServlet() {
		super();
	}

	
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}

	
	public void doGet(HttpServletRequest request,HttpServletResponse response)
			throws ServletException,IOException {

		this.execute(request,response);
	}

	public void doPost(HttpServletRequest request,response);
	}
	
	private void execute(HttpServletRequest request,HttpServletResponse resp){
		  resp.setCharacterEncoding("utf-8");		  
		  Cookie [] cs=request.getCookies();
		  System.out.println("cookies:"+( cs==null?0:cs.length));
		 Cookie c=new Cookie("tongguo","true");
		resp.addCookie(c);
		  resp.addHeader("Access-Control-Allow-Origin","http://localhost:8083");//注意此处		   	
		   List<UserInfo> tempt=_getSomeInfos();
		   JSONObject jobj=new JSONObject();
		   jobj.put("rows",tempt);
		   System.out.println(jobj);
		   byte[] jsonBytes;
		try {
			jsonBytes = jobj.toString().getBytes("utf-8");
			resp.setContentLength(jsonBytes.length);  
			resp.getOutputStream().write(jsonBytes);  
			resp.getOutputStream().flush();  
			resp.getOutputStream().close(); 
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
	}
	 @Override
	protected void doOptions(HttpServletRequest req,HttpServletResponse resp)
			throws ServletException,IOException {
		 resp.addHeader("Access-Control-Allow-Origin","http://localhost:8083");		
		  resp.addHeader("Access-Control-Max-Age","1728000");		
		  resp.addHeader("Access-Control-Allow-Methods","GET,POST,OPTIONS"); 
		  resp.addHeader("Access-Control-Allow-Headers","User-Agent,Origin,Cache-Control,Content-type,x-zd,Date,Server,withCredentials");
//注意此处不要再调用super.dooptions方法	  
		  
	}

	private List<UserInfo> _getSomeInfos() {
			List<UserInfo> result=new ArrayList<UserInfo>();
			UserInfo u=null;
			for(int i=0;i<30;i++){
				
				u=new UserInfo();
				u.setUsername("zhang"+i);
				if(i%2==0){
					u.setSex("Female");
					u.setAddress("四川");
					u.setSchool("CSU");
				}else{
					u.setSex("Male");
					u.setAddress("湖南长沙");
					u.setSchool("CWNU");
				}
				result.add(u);		
			}
			Collection nuCon = new Vector();
			nuCon.add(null);
			result.removeAll(nuCon);
			return result;
			
		}	
}

结果:发出了两次请求。第一次是options请求,第二次是get请求。






2.是使用CORS,发送一些带凭据的跨域请求,所谓的凭据就是一些cookie,HTTP认证什么的。摘录一段文档:

The most interesting capability exposed by bothXMLHttpRequestand Access Control is the ability to make "credentialed"requests that are cognizant of HTTPCookies and HTTPAuthentication information. By default,in cross-siteinvocations,browsers willnotsend credentials. A specific flag has to be set on theobject when it is invoked.

一般默认情况下都是不启用带有凭据的跨域,因此如果想要启用的话,只需将XMLHttpRequest的withCredentials属性设置为True,注意此处从服务器返回来的cookie信息以及响应头信息,可以通过浏览器显示出来,但是在js中不能用代码进行访问。

js代码

<script type="text/javascript">
	function crosFunc(){
		var xhr=new XMLHttpRequest();
		xhr.onreadystatechange=function(){
			if(xhr.readyState==4){
				if(xhr.status>=200&&xhr.status<=300||xhr.status==304){
				console.log("--->"+xhr.getAllResponseHeaders());//为空,不能访问返回的头信息
					console.log(xhr.responseText);
					console.log(console.log(document.cookie));//username=444  undefined  因为同源策略的影响,访问不到从服务器返回来的cookie
				}
				else{
					alert("cros Failed!");
				}

			}
		}
				if('withCredentials' in xhr){//检测xhr是否支持CORS,如果不支持,说明是ie,就只能使用XDomainRequest进行跨域
				console.log("it is true");
				}
		xhr.open('get',true);
	setCookie("username","444",12);
	xhr.setRequestHeader('x-zd','zd');
	xhr.withCredentials = "true";//向服务器说明我要发送带凭据的请求
		xhr.send(null);
		
	}
crosFunc();
function setCookie(key,value,hour){
		var _cookie=key+"="+encodeURIComponent(value);
		if(hour>0){
			var date=new Date();
			date.setTime(date.getTime()+hour*3600*1000);
			_cookie+=";expires="+date.toGMTString();
		}
		document.cookie=_cookie;
	}

java代码,只是在doOptionsexecute方法中各加入了同一行代码

resp.addHeader("Access-Control-Allow-Credentials","true");

结果:也是发出了两个请求,options请求和上面的一样,只看get请求:


刷新该页面,可以发现,发出带有cookie的请求:

同时在控制台查看响应的头部,主体内容,和cookie信息:

猜你在找的Ajax相关文章