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

摘要:
Global指示是否触发全局ajax事件。设置为false不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。AJAX跨域请求//注:转载自https://blog.csdn.net/csdn_ds/article/details/73691134对于AJAX,上述方法只能在同一域名下请求访问。如果我们需要请求跨域访问,我们应该怎么做?这是由浏览器的同源策略引起的,这是浏览器对JavaScript施加的安全限制。前端实施。以Jquery的ajax方法为例:1$ajax;此时服务器返回的不是一个普通的json字符串,而是一段可以由前端js执行的js代码。

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

AJAX的应用范围:

  登录失败不跳转页面

  注册时验证用户是否存在

  图片服务器进行延时加载

  多页数据进行翻页

  自动制新页面等。

AJAX的写法:

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

   这里是一个最简单的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方法为例:

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

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

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

json格式:

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

jsonp格式:

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

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

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

 1 package com.tooklili.app.web.util;
 2  
 3 import javax.servlet.http.HttpServletRequest;
 4  
 5 import org.apache.commons.lang.StringUtils;
 6 import org.springframework.web.context.request.RequestContextHolder;
 7 import org.springframework.web.context.request.ServletRequestAttributes;
 8  
 9 import com.fasterxml.jackson.databind.util.JSONPObject;
10  
11 /**
12  * 
13  * @author ding.shuai
14  * @date 2016年8月15日上午9:47:02
15  */
16 public class AppUtil {
17     
18     /**
19      * 判断json字符串是否需要转化成jsonp格式
20      * @param request
21      * @param result
22      * @return
23      */
24     public static Object conversionJsonp(Object result){
25         HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
26         return conversionJsonp(request, result);
27     }
28     
29  
30     public static Object conversionJsonp(HttpServletRequest request,Object result){
31         String callback = request.getParameter("callback");
32         if(StringUtils.isNotEmpty(callback)){
33             return new JSONPObject(callback, result);
34         }
35         return result;
36     }
37 }

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。

 1 package com.tooklili.app.web.filter;
 2  
 3 import java.io.IOException;
 4  
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.HttpServletResponse;
12  
13 /**
14  * 设置公共属性的过滤器
15  * @author shuai.ding
16  *
17  * @date 2017年6月21日上午11:02:27
18  */
19 public class CommonSetFilter implements Filter{
20  
21     @Override
22     public void init(FilterConfig filterConfig) throws ServletException {        
23     }
24  
25     @Override
26     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
27             throws IOException, ServletException {
28         //解决跨域问题
29         HttpServletResponse httpServletResponse =(HttpServletResponse)response;
30         // 指定允许其他域名访问 
31         httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
32         // 响应类型 
33         httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST");
34         // 响应头设置 
35         httpServletResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
36         
37         chain.doFilter(request, response);
38     }
39  
40     @Override
41     public void destroy() {    
42     }
43  
44 }

此处说明一下,笔者亲测:只设置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跨域请求》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Bootstrap表格Bean的三种实例化方式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

AJAX全套

概述  对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上。 AJAX类似于偷偷像后台发送数据。 1、传统的Web应用 一个简单操作需要重新加载全局数据 2、AJAX AJAX,Asynchronous JavaScript and XML (异步的Ja...

微信小程序开发五:案例实践

5.1天气预报 在这一节中,我们将开发一个天气预报的小程序,使用的数据接口为百度天气预报的接口,该接口可以根据经纬度坐标查询所在地天气。准备工作使用百度接口需要预先申请。在本书第4章中有百度ak的申请方法以及百度天气预报接口介绍。所不同的是第4章使用城市名称查询天气,而本节中使用坐标进行查询。在小程序中,将会向该地址发起请求,需要预先将百度接口所在域...

git subtree有效管理公共第三方lib

  如果你的项目中有很多第三方的lib,你希望使用它,并且也希望可能对该lib做修改并且贡献到原始的项目中去,或者你的项目希望模块化,分为几个repo单独维护,那么git subtree就是一个选择。git subtree管理的子项目在父项目中作为一个完整的代码copy存在,并不包含历史信息。综合考虑git subtree和git submodule的优缺...

cocos2dx 实现应用内屏幕旋转,ios端弹出虚拟键盘导致界面显示异常的问题

项目上遇到这样的需求,总体界面要横屏,但是部分界面需要切换到竖屏,同时横竖屏的界面都会有编辑框。 网上目前有很多资料涉及到这个的,安卓端实现很简单,横竖屏切换两三行代码就可以实现;ios端网上目前也有方案,比安卓稍微复杂点,但是也可以实现。但是涉及到界面上有编辑框,会弹出输入键盘的时候,ios端的界面就会出现异常。目前引擎对于编辑框的处理,在弹出键盘的时候...

git分支概念与项目中的应用

文档:https://git-scm.com/book/zh/v2/Git-分支-分支简介 分支理解 master分支是项目在创建时候的默认分支,除此之外,它并没有更多的含义。 剩下的 “开发分支”,“灰度分支”, “预发布分支”, “需求分支”,“测试分支” 都是根据项目和需求约定的。它们本质上只是一个分支而已。 分支在项目中的应用 1、首先,我们创...

在Windows上搭建Git Server

作为版本控制工具大多公司会选用Git,但svn也具有一定的优势,在对开源项目管理方面,Git具有一定的优势,我们可以将自己的项目放到GitHub上面,供大家交流学习,但一些企业项目和需要保密的闭源项目如果选择使用GitHub托管的话就会收取昂贵的费用。 所以对于一些公司项目就需要搭建自己的本地Git服务器,浏览大量网页后发现基本绝大部分Git服务都是在Li...