AJAX(Asynchronous javascript AND xml :异步javascript和xml):是一种创建交互式网页应用的网页开发技术。AJAX可以在不重新加载整个页面的情况下与服务器进行交互。

AJAX的应用范围:

  登录失败不跳转页面

  注册时验证用户是否存在

  图片服务器进行延时加载

  多页数据进行翻页

  自动制新页面等。

AJAX的写法:

 $.ajax({
url:"请求地址",
type:"请求方式",
data:"请求数据",
dataType:"服务器响应的数据类型",
success:function(msg){
//请求成功要做的事,msg:服务器响应的数据
},请求成功后的回调函数
error:function(XMLHttpRequest,textStatus,errorThrown){ } 请求失败或者超时的回调函数
})

  这里是一个最简单的ajax请求,其中包括的参数还有很多,见下表:

参数 值/描述
url 发送请求的地址,一般为string类型
type 请求的方式,值一般为:get/post
async 设置请求为异步还是同步请求,值:true(默认):异步请求、false:同步请求
data 需要向服务器发送的请求数据,值要以key/value的格式,如{name:"123",pwss:"123"}如果请求方式为get,会将数据连接到url上
datatype 服务器返回过来的数据类型是以什么格式返回的,值:xml、html、script、json、jsonp,text
timeout 设置本地请求超时时间,单位:毫秒。此设置将覆盖$.ajaxSetup()方法的全局设置。
cache 表示浏览器是否缓存请求的页面,默认值为true
beforeSend 请求发送前要执行的函数。要求为Function类型的参数
complete 请求完成后要执行的函数。在success和error执行完后执行。参数也为Function
success 请求成功后所执行的回调函数。第一个参数为:服务器响应的dataType类型的数据,第二个参数是描述状态的字符串,第三个为XMLHttpRequest对象
error 请求失败后所执行的回调函数。第一个参数为XMLHttpRequest对象,第二个为描述状态的字符,每三个为error异常
contentType 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
dataFilter 用于处理 XMLHttpRequest 原始响应数据的函数。
username 要求为String类型的参数,用于响应HTTP访问认证请求的用户名。
password 要求为String类型的参数,用于响应HTTP访问认证请求的密码。
global 表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。
ifModified 仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false。
jsonp 在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。
processData 默认为true,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false。
scriptCharset 只有当请求时dataType为"jsonp"或者"script",并且type是GET时才会用于强制修改字符集(charset)。通常在本地和远程的内容编码不同时使用。

  

AJAX跨域请求

  //注:转载自https://blog.csdn.net/csdn_ds/article/details/73691134

  以上的方法对于AJAX来说只能在同下个域名下进行请求访问,如果我们需要跨域请求要怎么做呢?

  如果AJAX出现跨域请求,浏览器就会报:XMLHttpRequest cannot load http://目标地址No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://当前页面地址' is therefore not allowed access. 错误

  为什么会出现跨域问题

    跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。

    在此说明一下,所谓的同源,指的是域名、协议、端口均相等。举例如下:

    http://www.abc.com/a/b 调用 http://www.abc.com/d/c(非跨域)

    http://www.abc.com/a/b 调用 http://www.def.com/d/c (跨域:域名不一致)

    http://www.abc.com:81/a/b 调用 http://www.abc.com:82/d/c (跨域:端口不一致)

    http://www.abc.com/a/b 调用 https://www.abc.com/d/c (跨域:协议不同)

    请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

  解决跨域问题有以下三种方法:

    1、使用jsonp

    2、服务器代理

    3、在服务端设置response header中Access-Control-Allow-Origin字段。

  1、使用jsonp

    jsonp解决跨域问题的原理是,浏览器的script标签是不受同源策略限制的,我们可以在script标签中访问任何域名下的资源文件。利用这一特性,用script标签从服务器中请求数据,同时服务器返回一个带有方法和数据的js代码,请求完成,调用本地的js方法,来完成数据的处理。

前端实现,以Jquery的ajax方法为例:

 $.ajax({
url:"",
dataType:'jsonp',
data:'',
jsonp:'callback', //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback) success:function(result) {
//成功的处理
},
error:function(){
//错误处理
}
});

服务端此时返回的不能是普通的json字符串,而是一段可以被前端js执行的一段js代码。

比较一下json与jsonp格式的区别:

json格式:

 {
"message":"获取成功",
"state":"1",
"result":{"name":"工作组1","id":1,"description":"11"}
}

jsonp格式:

 callback({
"message":"获取成功",
"state":"1",
"result":{"name":"工作组1","id":1,"description":"11"}
})

从格式来看,jsonp是在json的基础上包装了一个方法名,此方法名是前端请求传过来的,如请求地址为:http://localhost:9999/tookApp/tbk/getItem?callback=JSONP_CALLBACK,那么方法名就是JSONP_CALLBACK。

下面提供一段java代码,对象转jsonp的工具类:

 package com.tooklili.app.web.util;

 import javax.servlet.http.HttpServletRequest;

 import org.apache.commons.lang.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import com.fasterxml.jackson.databind.util.JSONPObject; /**
*
* @author ding.shuai
* @date 2016年8月15日上午9:47:02
*/
public class AppUtil { /**
* 判断json字符串是否需要转化成jsonp格式
* @param request
* @param result
* @return
*/
public static Object conversionJsonp(Object result){
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
return conversionJsonp(request, result);
} public static Object conversionJsonp(HttpServletRequest request,Object result){
String callback = request.getParameter("callback");
if(StringUtils.isNotEmpty(callback)){
return new JSONPObject(callback, result);
}
return result;
}
}

jsonp的缺点:

1、JSONP是一种非官方的方法,而且这种方法只支持GET方法,不如POST方法安全。(从实现机制就可明白)。

2、JSONP的实现需要服务器配合,如果是访问的是第三方的服务器,我们没有修改服务器的权限,那么这种方式是不可行的。

2、服务器代理

这种方式运用的就是服务器的反向代理技术,控制客户端和服务器的访问都从代理服务器经过,比如用nginx作为服务器代理,在nginx上配置客户端和第三方服务的反向代理,这样就可保证客户端、第三方是同源的了,同一个源,都来自代理服务器。

关于nginx的反向代理配置,可访问我的这篇博客:http://blog.csdn.net/csdn_ds/article/details/58605591

服务器代理的缺点:

开发比较麻烦,对开发环境比较严格,需要在本机上配置代理服务器。

优点:

完美解决使用jsonp,第三方服务没有修改权限的问题。程序的代码侵入性小,代码级别不需要考虑跨域问题。

3、在服务端设置response header中Access-Control-Allow-Origin字段

在被请求的Response Header中加入如下代码:

如果所有请求都想让其他域名的服务通过浏览器ajax请求到,可以通过Filter统一设置response header。

 package com.tooklili.app.web.filter;

 import java.io.IOException;

 import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse; /**
* 设置公共属性的过滤器
* @author shuai.ding
*
* @date 2017年6月21日上午11:02:27
*/
public class CommonSetFilter implements Filter{ @Override
public void init(FilterConfig filterConfig) throws ServletException {
} @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//解决跨域问题
HttpServletResponse httpServletResponse =(HttpServletResponse)response;
// 指定允许其他域名访问
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
// 响应类型
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST");
// 响应头设置
httpServletResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type"); chain.doFilter(request, response);
} @Override
public void destroy() {
} }

此处说明一下,笔者亲测:只设置Access-Control-Allow-Origin属性也是可以的。

Access-Control-Allow-Origin:* 表示允许任何域名跨域访问

如果需要指定某域名才允许跨域访问,只需把Access-Control-Allow-Origin:*改为Access-Control-Allow-Origin:允许的域名

例如:response.setHeader(“Access-Control-Allow-Origin”,”http://www.client.com”);

缺点:

1、此种解决跨域方案,需要浏览器支持H5,因为这是HTML5解决跨域的方式,如果产品面向的是PC端,这种方式可能就不是一个好的解决方案,如果面向的是手机端,此方法不为一个简单、粗暴的好方式。

2、设置*,存在安全隐患。

4、总结

综上三种解决跨域的方案,个人感觉使用服务代理最好,没有破坏浏览器的安全策略,但这个对开发环境要高一点。设置response header的方式,根据具体情况分析,要考虑清楚产品面向的用户。对于jsonp这种方式,虽然没有破坏浏览器的安全策略,但只支持get方式的请求,有点不能接受,因为get传输有参数长度的限制,同时又要考虑传输中文的乱码问题,但如果项目中只是简单的查询、展示,这种方式还是可以考虑的。

其他好文推荐

Access-Control-Allow-Origin 跨域设置多域名:http://www.jianshu.com/p/b587dd1b7086

JQ之$.ajax()方法以及ajax跨域请求的更多相关文章

  1. Springboot如何优雅的解决ajax+自定义headers的跨域请求

    1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发 ...

  2. Springboot如何优雅的解决ajax+自定义headers的跨域请求[转]

    1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发 ...

  3. Ajax+Spring MVC实现跨域请求(JSONP)JSONP 跨域

    JSONP原理及实现 接下来,来实际模拟一个跨域请求的解决方案.后端为Spring MVC架构的,前端则通过Ajax进行跨域访问. 1.首先客户端需要注册一个callback(服务端通过该callba ...

  4. Ajax 调用webservice 解决跨域请求和发布到服务器后本地调用成功外网失败的问题

        webservice 代码 /// <summary> /// MESService 的摘要说明 /// </summary> [WebService(Namespac ...

  5. Ajax+Spring MVC实现跨域请求(JSONP)(转)

    背景: AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源.可 ...

  6. Ajax+Spring MVC实现跨域请求(JSONP)

    背景: AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源.可 ...

  7. Ajax操作如何实现跨域请求 (JSONP和CORS实现Ajax跨域的原理)

    由于浏览器存在同源策略机制,同源策略阻止ajax (XMLHttpRequest) 从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响 ...

  8. jQuery Ajax 简单的实现跨域请求

    html 代码清单: <script type="text/javascript" src="http://www.youxiaju.com/js/jquery-1 ...

  9. ajax发送多个跨域请求回调不混乱

    var count = 0; var codes = ""; function refreshCache(urls){ try { var url = urls.split(&qu ...

  10. JSONP跨域请求数据报错 “Unexpected token :”的解决办法

    原文  http://www.cnphp6.com/archives/65409 Jquery使用ajax方法实现jsonp跨域请求数据的时候报错 “Uncaught SyntaxError: Une ...

随机推荐

  1. easyui---accordion(手风琴)

    首先配置好easyui环境 1.ACCORDION(手风琴) class:class=easyui-accordion, 事件: 查找: function selectPanel(){ //会弹出输入 ...

  2. tomcat7 fail to start inside Ubuntu Docker container

    The tomcat startup script needs some special privileges. Concrete it needs to check all running proc ...

  3. CUBE 隐藏维度中的Unknown

     纬度,属性里面有个unknowmember设置为hidden   

  4. opencv作业

    作业下载地址: 链接:http://pan.baidu.com/s/1qYQnbkw 密码:v7y9

  5. 《springcloud 五》springcloud stream

    什么是消息驱动? SpringCloud Stream消息驱动可以简化开发人员对消息中间件的使用复杂度,让系统开发人员更多尽力专注与核心业务逻辑的开发.SpringCloud Stream基于Spri ...

  6. SlickEdit 18.0 版本发布 同时更新破解文件

    18.0版本没有太大的惊喜 多了如下功能 Multiple Document Group Interface Repository Log Browser History Diff Support f ...

  7. 【extjs6学习笔记】1.7 初始:加载第三方库

    https://www.sencha.com/blog/integrating-ext-js-with-3rd-party-libraries-2/ Introduction Ext JS provi ...

  8. json格式引起的 parse 报错

    json格式: {"ID":"4","PICDATAS":"[{"picDevNo": 1},{"p ...

  9. 监测元素resize

    前言 近来有需求要做分页,听起来可能有点Low. 所以我要把Low的事情做得有点逼格. 分页本身没啥,但是数据量起来了,比如十万. 要是不做点处理, 那你的页面估计爽得很,机器也爽得很. 放心,我不会 ...

  10. PHP的优良习惯(转)

    1.多阅读手册和源代码 没什么比阅读手册更值得强调的事了–仅仅通过阅读手册你就可以学习到很多东西,特别是很多有关于字符串和数组的函数.就在这些函数里面包括许多有用的功能,如果你仔细阅读手册,你会经常发 ...