主要是针对非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 will

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

CORS 使用ajax+servlet实现的更多相关文章

  1. HTML5新增form控件和表单属性实例代码详解

    这篇文章主要介绍了HTML5新增form控件和表单属性实例代码详解,需要的朋友可以参考下

  2. HTML5表单验证特性(知识点小结)

    这篇文章主要介绍了HTML5表单验证特性的一些知识点,本文通过实例代码截图的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. amazeui页面分析之登录页面的示例代码

    这篇文章主要介绍了amazeui页面分析之登录页面的示例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. ios – Swift Eureka Form中的循环

    我正在构建一个Eureka表单,并希望在表单中放置一个循环来构建基于数组的步进器列表.我试图使用的代码是:但是,当我这样做时,我在StepperRow行上出现了一个错误:所以看起来Swift不再认为它在形式之内并且正在关注

  5. swift 上传图片和参数 upload image with params

    Alamofire.upload(urlRequest.0,urlRequest.1).progress{(bytesWritten,totalBytesWritten,totalBytesExpectedToWrite)inprintln("\(totalBytesWritten)/\(totalBytesExpectedToWrite)")}}

  6. swift – 使用PostgreSQL在Vapor 3中上传图片

    我正在关注这些家伙MartinLasek教程,现在我正在“图片上传”.似乎没有人能回答“如何上传iVapor3图像”的问题Db连接正常,所有其他值都保存.这是我的创建方法:和型号:}和叶子模板:我知道需要一种管理文件的方法和原始图像字节,但我怎么去那里?这使用多部分表单的自动解码:upload.leaf文件是:使用File类型可以访问上载文件的本地文件名以及文件数据.如果将其余的Question字段添加到ExampleUpload结构中,则可以使用该路径捕获整个表单的字段.

  7. 简单易懂的JSONP和CORS跨域方案详解

    这篇文章主要为大家介绍了简单易懂的JSONP和CORS跨域方案详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  8. 如何防止IE缓存jsp文件

    1,使用java提供的方法,在jsp或者servlet中都可以2,使用HTML标记,如下面:

  9. HTML form表单提交方法案例详解

    这篇文章主要介绍了HTML form表单提交方法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  10. 解决Django cors跨域问题

    这篇文章主要介绍了解决Django cors跨域问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

随机推荐

  1. xe-ajax-mock 前端虚拟服务

    最新版本见Github,点击查看历史版本基于XEAjax扩展的Mock虚拟服务插件;对于前后端分离的开发模式,ajax+mock使前端不再依赖后端接口开发效率更高。CDN使用script方式安装,XEAjaxMock会定义为全局变量生产环境请使用xe-ajax-mock.min.js,更小的压缩版本,可以带来更快的速度体验。

  2. vue 使用 xe-ajax

    安装完成后自动挂载在vue实例this.$ajaxCDN安装使用script方式安装,VXEAjax会定义为全局变量生产环境请使用vxe-ajax.min.js,更小的压缩版本,可以带来更快的速度体验。cdnjs获取最新版本点击浏览已发布的所有npm包源码unpkg获取最新版本点击浏览已发布的所有npm包源码AMD安装require.js安装示例ES6Module安装通过Vue.use()来全局安装示例./Home.vue

  3. AJAX POST数据中文乱码解决

    前端使用encodeURI进行编码后台java.net.URLDecoder进行解码编解码工具

  4. Koa2框架利用CORS完成跨域ajax请求

    实现跨域ajax请求的方式有很多,其中一个是利用CORS,而这个方法关键是在服务器端进行配置。本文仅对能够完成正常跨域ajax响应的,最基本的配置进行说明。这样OPTIONS请求就能够通过了。至此为止,相当于仅仅完成了预检,还没发送真正的请求呢。

  5. form提交时,ajax上传文件并更新到&lt;input&gt;中的value字段

  6. ajax的cache作用

    filePath="+escape;},error:{alert;}});解决方案:1.加cache:false2.url加随机数正常代码:网上高人解读:cache的作用就是第一次请求完毕之后,如果再次去请求,可以直接从缓存里面读取而不是再到服务器端读取。

  7. 浅谈ajax上传文件属性contentType = false

    默认值为contentType="application/x-www-form-urlencoded".在默认情况下,内容编码类型满足大多数情况。在这里,我们主要谈谈contentType=false.在使用ajax上传文件时:在其中先封装了一个formData对象,然后使用post方法将文件传给服务器。说到这,我们发现在JQueryajax()方法中我们使contentType=false,这不是冲突了吗?这就是因为当我们在form标签中设置了enctype=“multipart/form-data”,

  8. 909422229_ajaxFileUpload上传文件

    ajaxFileUpload.js很多同名的,因为做出来一个很容易。我上github搜AjaxFileUpload出来很多类似js。ajaxFileUpload是一个异步上传文件的jQuery插件传一个不知道什么版本的上来,以后不用到处找了。语法:$.ajaxFileUploadoptions参数说明:1、url上传处理程序地址。2,fileElementId需要上传的文件域的ID,即的ID。3,secureuri是否启用安全提交,默认为false。4,dataType服务器返回的数据类型。6,error

  9. AJAX-Cache:一款好用的Ajax缓存插件

    原文链接AJAX-Cache是什么Ajax是前端开发必不可少的数据获取手段,在频繁的异步请求业务中,我们往往需要利用“缓存”提升界面响应速度,减少网络资源占用。AJAX-Cache是一款jQuery缓存插件,可以为$.ajax()方法扩展缓存功能。

  10. jsf – Ajax update/render在已渲染属性的组件上不起作用

    我试图ajax更新一个有条件渲染的组件。我可以确保#{user}实际上是可用的。这是怎么引起的,我该如何解决呢?必须始终在ajax可以重新呈现之前呈现组件。Ajax正在使用JavaScriptdocument.getElementById()来查找需要更新的组件。但是如果JSF没有将组件放在第一位,那么JavaScript找不到要更新的内容。解决方案是简单地引用总是渲染的父组件。

返回
顶部