微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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 theOPTIONSmethod 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信息:

原文地址:https://www.jb51.cc/ajax/165015.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐