JQ之$.ajax()方法以及ajax跨域请求
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跨域请求的更多相关文章
- Springboot如何优雅的解决ajax+自定义headers的跨域请求
1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发 ...
- Springboot如何优雅的解决ajax+自定义headers的跨域请求[转]
1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发 ...
- Ajax+Spring MVC实现跨域请求(JSONP)JSONP 跨域
JSONP原理及实现 接下来,来实际模拟一个跨域请求的解决方案.后端为Spring MVC架构的,前端则通过Ajax进行跨域访问. 1.首先客户端需要注册一个callback(服务端通过该callba ...
- Ajax 调用webservice 解决跨域请求和发布到服务器后本地调用成功外网失败的问题
webservice 代码 /// <summary> /// MESService 的摘要说明 /// </summary> [WebService(Namespac ...
- Ajax+Spring MVC实现跨域请求(JSONP)(转)
背景: AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源.可 ...
- Ajax+Spring MVC实现跨域请求(JSONP)
背景: AJAX向后台(springmvc)发送请求,报错:已阻止交叉源请求:同源策略不允许读取 http://127.0.0.1:8080/DevInfoWeb/getJsonp 上的远程资源.可 ...
- Ajax操作如何实现跨域请求 (JSONP和CORS实现Ajax跨域的原理)
由于浏览器存在同源策略机制,同源策略阻止ajax (XMLHttpRequest) 从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响 ...
- jQuery Ajax 简单的实现跨域请求
html 代码清单: <script type="text/javascript" src="http://www.youxiaju.com/js/jquery-1 ...
- ajax发送多个跨域请求回调不混乱
var count = 0; var codes = ""; function refreshCache(urls){ try { var url = urls.split(&qu ...
- JSONP跨域请求数据报错 “Unexpected token :”的解决办法
原文 http://www.cnphp6.com/archives/65409 Jquery使用ajax方法实现jsonp跨域请求数据的时候报错 “Uncaught SyntaxError: Une ...
随机推荐
- C 语言实例 - 判断正数/负数
C 语言实例 - 判断正数/负数 用户输入一个数字,判断该数字是正数还是负数或是零. 实例 #include <stdio.h> int main() { double number; p ...
- IOS 打包提示 No iTunes Connect access for the team
1.可以在提示页直接点击 Manage Accounts按钮,进去页面后,选择开发者账号点减号删除:(或者在Xcode中直接按command+键进入,选择accounts,选中账号按-键删除) 2.完 ...
- JAVAFX-2 开发应用
理解javafx 架构 ● 场景图(Scene Graph) ● JavaFX功能的公开API(Java Public APIs for JavaFX Features) ● 图形系统(Graphic ...
- Jmeter4.0----编写测试脚本(5)
1.说明 以HTTP请求为例,和小伙伴门分享一下jmeter测试脚本的基本编写步骤 2.步骤说明 第一步:打开jmeter,更改测试计划名称为 Test batchSignForDir(修改计划名称, ...
- EOJ Problem #3261 分词 trie + dp + 小剪枝
http://acm.ecnu.edu.cn/problem/3261/ 分词 Time limit per test: 1.0 seconds Time limit all tests: 1.0 s ...
- 远程调试工具weinre使用教程
一:前言 我们都知道,chrome的开发者工具(f12)是一个方便我们调试PC页面的工具.但是现在我们的开发离不开移动端,那如果我们需要对手机页面进行调试,那该怎么办了? 当然,chrome的开发者工 ...
- ruby YAML.load 和YAML.load_file区别
1. load( io ) Load a document from the current io stream. File.open( 'animals.yaml' ) { |yf| YAML::l ...
- .NET CORE IIS 500.21
最近遇到的.NET CORE 500.21的错误 官方解决方案地址:https://docs.microsoft.com/en-us/dynamics-nav/troubleshooting-http ...
- Linux常用操作详解
第1章 Linux命令基础 1.1 习惯 操作前备份,操作后检查 1.2 简单目录结构 一切从根开始,与windows不同 1.3 规则 [root@znix ~]# [用户名@主机名 你在哪]# 1 ...
- 常用浏览器User-Agent大全
=======================PC浏览器======================== OperaMozilla/5.0 (Windows NT 6.1; WOW64) AppleW ...