JQ之$.ajax()方法以及ajax跨域请求

时间:2022-09-12 13:29:52

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&plus;Spring MVC实现跨域请求(JSONP)&lpar;转&rpar;

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

  6. Ajax&plus;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跨域请求数据报错 &OpenCurlyDoubleQuote;Unexpected token &colon;”的解决办法

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

随机推荐

  1. C语言的可变参数在Linux&lpar;Ubuntu&rpar;与Windows下注意点

    基本上C语言的可变参数原理在不同平台和不同编译器下基本类似(通过函数入栈,从右向左,从高位到低位地址),不过部分实现会有所不同:在使用中需要注意的是: va_list 为char 类型指针,部分调用如 ...

  2. SQLSERER 中select排序问题

    SELECT  * FROM 表名 ORDER BY PageNO DESC 这种排序会排出这种效果:1, 11,2,20 select             *,              RIG ...

  3. Linux server关闭自己主动

    公司linux server发生错误.mysql server没有理由关闭,我找不到理由.Version: '5.6.13-enterprise-commercial-advanced' socket ...

  4. CoolBlog开发笔记第1课&colon;项目分析

    首先说一下CoolBlog开发笔记是我制作的<Django实战项目>系列教程基础篇的内容,使用Django来开发一个酷炫的个人博客,涉及的知识包括项目的分析,环境的搭建,模型和视图定义等等 ...

  5. vxWorks内核实现基本原理

    内核实现基本原理     VxWorks 内核维护三个队列:tick队列.ready 队列.active 队列.另外还有一个队列涉及任务,即任务等待资源时所处的队列,这个队列可以是VxWorks内核提 ...

  6. Spring Boot 2&period;0 配置图文教程

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 本章内容 自定义属性快速入门 外化配置 自动配置 自定义创建 ...

  7. python的出生

    1.语言的种类 机器语言------>汇编语言------>高级语言 高级语言按转换方式分为两类: 解释类:执行方式类似于我们日常生活中的“同声翻译”,应用程序源代码一边由相应语言的解释器 ...

  8. Revit API遍历全部风管,找到与风管相关的墙开洞

    涉及向量计算,求相交等相关技术. )                 {                     foreach (Face face in solid.Faces)          ...

  9. tensorflow 安装GPU版本,个人总结,步骤比较详细【转】

    本文转载自:https://blog.csdn.net/gangeqian2/article/details/79358543 手把手教你windows安装tensorflow的教程参考另一篇博文ht ...

  10. cas sso ajax的jsonp实现方案总结(新浪微薄、淘宝案例分析)

    Cas自定义登录页面Ajax实现:http://cydiay.iteye.com/blog/1738713 CAS 之 跨域 Ajax 登录实践:http://denger.iteye.com/blo ...