一、概述

AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

AJAX = 异步 JavaScript 和 XML,是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

本博客实验环境:

python:2.7.11web框架:tonado
jquery:2.1.1

二、“伪”AJAX

由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求,从而实现页面异步更新。

<!DOCTYPE html>
<html><headlang="en"><metacharset="UTF-8"><title></title></head><body><div><!--时间戳不变代表整个页面不刷新--><p>页面时间戳:<spanid="currentTime"></span></p><p>请输入要加载的地址:</p><p><inputid="url"type="text" /><inputtype="button"value="刷新"onclick="LoadPage();"></p></div><div><h3>加载页面位置:</h3><iframeid="iframePosition"style="width: 100%;height: 500px;"></iframe></div><scripttype="text/javascript">window.onload= function(){varmyDate= newDate();document.getElementById('currentTime').innerText=myDate.getTime();};functionLoadPage(){vartargetUrl=document.getElementById('url').value;//为iframe的src动态赋值
document.getElementById("iframePosition").src=targetUrl;}</script></body>
</html>

“伪”AJAX实例

三、原生AJAX

Ajax主要就是使用 【XmlHttpRequest】对象来完成请求的操作,该对象在主流浏览器中均存在(除早期的IE),Ajax首次出现IE5.5中存在(ActiveX控件)。

1、XmlHttpRequest对象介绍

XmlHttpRequest对象的主要方法:

a. void open(String method,String url,Boolen async)用于创建请求参数:method: 请求方式(字符串类型),如:POST、GET、DELETE...url:    要请求的地址(字符串类型)async:  是否异步(布尔类型),一般填trueb. void send(String body)用于发送请求参数:body: 要发送的数据(字符串类型)c. void setRequestHeader(String header,String value)用于设置请求头参数:header: 请求头的key(字符串类型)vlaue:  请求头的value(字符串类型)d. String getAllResponseHeaders()获取所有响应头返回值:响应头数据(字符串类型)e. String getResponseHeader(String header)获取响应头中指定header的值参数:header: 响应头的key(字符串类型)返回值:响应头中指定的header对应的值f. void abort()终止请求

XmlHttpRequest对象的主要属性:

a. Number readyState状态值(整数)详细:0-未初始化,尚未调用open()方法;1-启动,调用了open()方法,未调用send()方法;2-发送,已经调用了send()方法,未接收到响应;3-接收,已经接收到部分响应数据;4-完成,已经接收到全部响应数据;b. Function onreadystatechange当readyState的值改变时自动触发执行其对应的函数(回调函数)c. String responseText服务器返回的数据(字符串类型)d. XmlDocument responseXML服务器返回的数据(Xml对象)e. Number states状态码(整数),如:200、404...f. String statesText状态文本(字符串),如:OK、NotFound...

2、跨浏览器支持

XmlHttpRequest支持:
IE7+, Firefox, Chrome, Opera, etc.

IE6, IE5不支持XmlHttpRequest。,所以使用ActiveXObject("Microsoft.XMLHTTP")对象实现。

原生AJAX实例(支持XHR和ActiveXObject):

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><h1>XMLHttpRequest - Ajax请求</h1><input type="button" οnclick="XhrGetRequest();" value="Get发送请求" /><input type="button" οnclick="XhrPostRequest();" value="Post发送请求" /><script type="text/javascript">functionGetXHR(){var xhr = null;if(XMLHttpRequest){xhr= newXMLHttpRequest();}else{xhr= new ActiveXObject("Microsoft.XMLHTTP");}returnxhr;}functionXhrPostRequest(){var xhr =GetXHR();//定义回调函数xhr.onreadystatechange = function(){if(xhr.readyState == 4){//已经接收到全部响应数据,执行以下操作var data =xhr.responseText;alert(data);}};//指定连接方式和地址----文件方式xhr.open('POST', "/test", true);//设置请求头xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');//发送请求xhr.send('n1=1;n2=2;');}functionXhrGetRequest(){var xhr =GetXHR();//定义回调函数xhr.onreadystatechange = function(){if(xhr.readyState == 4){//已经接收到全部响应数据,执行以下操作var data =xhr.responseText;alert(data);}};//指定连接方式和地址----文件方式xhr.open('get', "/test", true);//发送请求
xhr.send();}</script></body>
</html>

原生AJAX前端代码

#! /usr/bin/env python
# -*- coding:utf-8 -*-# __author__= "TKQ"#! /usr/bin/env python
# -*- coding:utf-8 -*-# __author__= "TKQ"import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.webfrom tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)class IndexHandler(tornado.web.RequestHandler):def get(self):self.render("AJAX.html")class TestHandler(tornado.web.RequestHandler):def get(self):self.write("hello ajax get method!")def post(self):n1=self.get_argument("n1")n2=self.get_argument("n2")addvalue=int(n1)+int(n2)self.write("n1+n2=%s"%addvalue)if __name__ == "__main__":tornado.options.parse_command_line()app=tornado.web.Application(handlers=[(r"/", IndexHandler),(r"/test",TestHandler)],template_path="template")http_server=tornado.httpserver.HTTPServer(app)http_server.listen(options.port)tornado.ioloop.IOLoop.instance().start()

后端tornado代码

四、jQuery Ajax

jQuery其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能。

  • jQuery 不是生产者,而是大自然搬运工。
  • jQuery Ajax本质 XMLHttpRequest 或 ActiveXObject

注:2.+版本不再支持IE9以下的浏览器

jQuery.ajax(...)部分参数:url:请求地址type:请求方式,GET、POST(1.9.0之后用method)headers:请求头data:要发送的数据contentType:即将发送信息至服务器的内容编码类型(默认:"application/x-www-form-urlencoded; charset=UTF-8")async:是否异步timeout:设置请求超时时间(毫秒)beforeSend:发送请求前执行的函数(全局)complete:完成之后执行的回调函数(全局)success:成功之后执行的回调函数(全局)error:失败之后执行的回调函数(全局)accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型dataType:将服务器端返回的数据转换成指定类型"xml": 将服务器端返回的内容转换成xml格式"text": 将服务器端返回的内容转换成普通文本格式"html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。"script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式"json": 将服务器端返回的内容转换成相应的JavaScript对象"jsonp": JSONP 格式使用 JSONP 形式调用函数时,如"myurl?callback=?" jQuery 将自动替换 ?为正确的函数名,以执行回调函数如果不指定,jQuery 将自动根据HTTP包MIME信息返回相应类型(an XML MIME type will yield XML,in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything elsewill be returned as a stringconverters: 转换器,将服务器端的内容根据指定的dataType转换类型,并传值给success回调函数$.ajax({accepts: {mycustomtype:'application/x-some-custom-type'},//Expect a `mycustomtype` back from serverdataType: 'mycustomtype'//Instructions for how to deserialize a `mycustomtype`
converters: {'text mycustomtype': function(result) {//Do Stuffreturnnewresult;}},});

Jquery底层AJAX方法

jQuery.get(...)所有参数:url: 待载入页面的URL地址data: 待发送 Key/value 参数。
success: 载入成功时回调函数。dataType: 返回内容格式,xml, json,  script, text, htmljQuery.post(...)所有参数:url: 待载入页面的URL地址data: 待发送 Key/value 参数
success: 载入成功时回调函数dataType: 返回内容格式,xml, json,  script, text, htmljQuery.getJSON(...)所有参数:url: 待载入页面的URL地址data: 待发送 Key/value 参数。
success: 载入成功时回调函数。jQuery.getScript(...)所有参数:url: 待载入页面的URL地址data: 待发送 Key/value 参数。success: 载入成功时回调函数。

封装请求方法的AJAX方法

Jquery AJAX实例:

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><p><input type="button" οnclick="JqSendRequest();" value='Ajax请求' /></p><script type="text/javascript" src='{{static_url("jquery-2.1.1.min.js")}}'></script><script>functionJqSendRequest(){$.ajax({url:"/test",type:'GET',dataType:'text',success:function(data, statusText, xmlHttpRequest){console.log(data, statusText, xmlHttpRequest)}})}</script>
</body>
</html>

Jquery实例前端

#! /usr/bin/env python
# -*- coding:utf-8 -*-# __author__= "TKQ"#! /usr/bin/env python
# -*- coding:utf-8 -*-# __author__= "TKQ"import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.webfrom tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)class IndexHandler(tornado.web.RequestHandler):def get(self):self.render("JQ.html")class TestHandler(tornado.web.RequestHandler):def get(self):self.write("hello ajax get method!")def post(self):n1=self.get_argument("n1")n2=self.get_argument("n2")addvalue=int(n1)+int(n2)self.write("n1+n2=%s"%addvalue)if __name__ == "__main__":tornado.options.parse_command_line()app=tornado.web.Application(handlers=[(r"/", IndexHandler),(r"/test",TestHandler)],template_path="template",static_path= 'statics')http_server=tornado.httpserver.HTTPServer(app)http_server.listen(options.port)tornado.ioloop.IOLoop.instance().start()

后端tornado代码

五、跨域AJAX

由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。

关于同源的判定规则:如果两个页面拥有相同的协议(protocol),端口(如果指定),和主机,那么这两个页面就属于同一个源(origin)。

URL 结果 原因
http://store.company.com/dir/page.html 参照对象
http://store.company.com/dir2/other.html 成功  
http://store.company.com/dir/inner/another.html 成功  
https://store.company.com/secure.html 失败 协议不同
http://store.company.com:81/dir/etc.html 失败 端口不同
http://news.company.com/dir/other.html 失败 主机名不同

特别的:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接受罢了。

浏览器同源策略并不是对所有的请求均制约:

  • 制约: XmlHttpRequest
  • 无效: img、iframe、script等具有src属性的标签

那么如有解决跨域请求的问题呢?下面提供了两中方法实现跨域请求,分别是JSONP和CORS。

Jsonp 与 CORS 的比较:

  • Jsonp只支持 GET 请求,CORS支持所有类型的HTTP请求。
  • Jsonp 的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

1、JSONP实现跨域请求

JSONP(JSONP - JSON with Padding是JSON的一种“使用模式”),利用script标签的src属性(浏览器允许script标签跨域)。

基本原理,通过以下几步完成跨域请求:

  1、brower创建script标签,并利用script标签的src属性发送跨域请求,获取服务器的返回值在<script>标签内。
  2、server返回函数调用语句(myfunc(args);),并将需要返回的值(args)作为函数参数一并返回。

  3、brower执行服务器返回的调用函数的语句(myfunc(args)),对返回值进行操作。

  4、brower删除第一步创建的script标签。

 JSONP实例一,固定回调函数名:

#! /usr/bin/env python
# -*- coding:utf-8 -*-# __author__= "TKQ"import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.webfrom tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)class IndexHandler(tornado.web.RequestHandler):def get(self):self.render("jsonp.html")class TestHandler(tornado.web.RequestHandler):def get(self):#客户端定义的函数名必须也为myfunc才会调用self.write("myfunc([1,2,3]);")if __name__ == "__main__":tornado.options.parse_command_line()app=tornado.web.Application(handlers=[(r"/", IndexHandler),(r"/test",TestHandler)],template_path="template",static_path= 'statics')http_server=tornado.httpserver.HTTPServer(app)http_server.listen(options.port)tornado.ioloop.IOLoop.instance().start()

后端tornado代码

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><p><input type="button" οnclick="GetJsonp();"  value='提交'/></p><!--<script type="text/javascript" src='{{static_url("jquery-2.1.1.min.js")}}'></script>--><script>
//创建script标签跨域请求,并根据返回函数myfunc([1,2,3]);执行定义的myfunc函数functionGetJsonp(){var tag = document.createElement('script');tag.src= "http://tkq2.com:8000/test";document.head.appendChild(tag);document.head.removeChild(tag);}functionmyfunc(list) {console.log(list);}</script>
</body>
</html>

原生jsonp实例

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><p><input type="button" οnclick="GetJsonp();"  value='提交'/></p><script type="text/javascript" src='{{static_url("jquery-2.1.1.min.js")}}'></script><script>
//创建script标签跨域请求,并根据返回函数myfunc([1,2,3]);执行定义的myfunc函数functionGetJsonp(){$.ajax({url:"http://tkq2.com:8000/test",dataType:'jsonp',jsonpCallback:'myfunc'  //自定义了回调函数名,默认为jQuery自动生成的随机函数名。如果不写回调函数名,默认执行与服务器返回的函数名相同的函数。
})}//回调函数functionmyfunc(list) {console.log(list);}</script>
</body>
</html>

Jquery的jsonp实例

JSONP实例二,可变回调函数名: 

实例一中,回调函数服务器端定写死了,请求端必须定义和服务器端相同函数名才行。但作为服务端应该有更好的兼容性,请求端自行决定回调函数名字,下面我们来实现这个功能。

原理:http://tkq2.com:8000/test?jsonpcallback=myfunc,通过请求中携带jsonpcallback=myfunc参数,使服务端获取到自定义的回调函数名。

#! /usr/bin/env python
# -*- coding:utf-8 -*-# __author__= "TKQ"import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.webfrom tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)class IndexHandler(tornado.web.RequestHandler):def get(self):self.render("jq_jsonp.html")class TestHandler(tornado.web.RequestHandler):def get(self):func_name=self.get_argument('jsonpcallback')self.write("%s([1,2,3]);" %func_name)if __name__ == "__main__":tornado.options.parse_command_line()app=tornado.web.Application(handlers=[(r"/", IndexHandler),(r"/test",TestHandler)],template_path="template",static_path= 'statics')http_server=tornado.httpserver.HTTPServer(app)http_server.listen(options.port)tornado.ioloop.IOLoop.instance().start()

后端tornado代码

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><p><input type="button" οnclick="GetJsonp();"  value='提交'/></p><!--<script type="text/javascript" src='{{static_url("jquery-2.1.1.min.js")}}'></script>--><script>
//创建script标签跨域请求,并根据返回函数myfunc([1,2,3]);执行定义的myfunc函数functionGetJsonp(){var tag = document.createElement('script');//自定义回调函数名,jsonpcallback=myfunc字段供服务端读取。tag.src = "http://tkq2.com:8000/test?jsonpcallback=myfunc";document.head.appendChild(tag);document.head.removeChild(tag);}functionmyfunc(list) {console.log(list);}

原生JS实现

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><p><input type="button" οnclick="GetJsonp();"  value='提交'/></p><script type="text/javascript" src='{{static_url("jquery-2.1.1.min.js")}}'></script><script>
//创建script标签跨域请求,并根据返回函数myfunc([1,2,3]);执行定义的myfunc函数functionGetJsonp(){$.ajax({url:"http://tkq2.com:8000/test",dataType:'jsonp',jsonp:'jsonpcallback',   //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)jsonpCallback:'myfunc'  //自定义了回调函数名,默认为jQuery自动生成的随机函数名。如果不写回调函数名,默认执行与服务器返回的函数名相同的函数。
})}//回调函数functionmyfunc(list) {console.log(list);}</script>
</body>
</html>

Jquery实现

JSONP实例三,江西卫视节目单获取:

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><p><input type="button" οnclick="GetJsonp();"  value='JS提交'/><input type="button" οnclick="JQJsonp();"  value='JQ提交'/></p><script type="text/javascript" src='{{static_url("jquery-2.1.1.min.js")}}'></script><script>//回调函数functionlist(data) {console.log(data);}functionGetJsonp(){var tag = document.createElement('script');tag.src= "http://www.jxntv.cn/data/jmd-jxtv2.html";document.head.appendChild(tag);document.head.removeChild(tag);}functionJQJsonp(){$.ajax({url:"http://www.jxntv.cn/data/jmd-jxtv2.html",dataType:'jsonp',jsonpCallback:'list'})}</script>
</body>
</html>

江西卫视节目单获取

 

2、CORS跨域资源共享

随着技术的发展,现在的浏览器可以支持主动设置从而允许跨域请求,即:跨域资源共享(CORS,Cross-Origin Resource Sharing),其本质是设置响应头,使得浏览器允许跨域请求。

这种实现方式:请求端和普通的AJAX方法相同,但服务器端需要做相应的配置。

 简单请求 OR 非简单请求

条件:1、请求方式:HEAD、GET、POST2、请求头信息:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type 对应的值是以下三个中的任意一个application/x-www-form-urlencodedmultipart/form-datatext/plain
注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求

CORS中简单请求和非简单请求的区别是什么?

简单请求:一次请求
非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。 

关于“预检”

-请求方式:OPTIONS-“预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息-如何“预检”=>如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过Access-Control-Request-Method=>如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过Access-Control-Request-Headers

基于cors实现AJAX请求:

a、支持跨域,简单请求

服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><h1>CORS</h1><input type="button" οnclick="XhrGetRequest();" value="Get发送请求" /><script type="text/javascript">functionXhrGetRequest(){var xhr =newXMLHttpRequest();xhr.onreadystatechange= function(){if(xhr.readyState == 4){var data =xhr.responseText;alert(data);}};xhr.open('get', "http://tkq2.com:8000/test", true);xhr.send();}</script></body>
</html>

HTML+JS

tonado设置:
class TestHandler(tornado.web.RequestHandler):def get(self):self.set_header('Access-Control-Allow-Origin', "http://tkq1.com:8000")self.write('cors get success')

b、支持跨域,复杂请求

由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

  • "预检“请求前,先需要设置预检接收源地址:Access-Control-Allow-Origin
  • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
  • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers
  • “预检”缓存时间,服务器设置响应头:Access-Control-Max-Age

预检完成后,在发送负载请求,例如put方法,该方法如同简单方法一样,需要设置接收源地址:Access-Control-Allow-Origin

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><h1>CORS</h1><input type="button" οnclick="XhrGetRequest();" value="put发送请求js" /><input type="button" οnclick="JqSendRequest();" value="put发送请求jq" /><script type="text/javascript" src='{{static_url("jquery-2.1.1.min.js")}}'></script><script type="text/javascript">functionXhrGetRequest(){var xhr =newXMLHttpRequest();xhr.onreadystatechange= function(){if(xhr.readyState == 4){var data =xhr.responseText;alert(data);}};xhr.open('put', "http://tkq2.com:8000/cors", true);xhr.setRequestHeader('h1', 'v1');xhr.send();}functionJqSendRequest(){$.ajax({url:"http://tkq2.com:8000/cors",type:'PUT',dataType:'text',headers: {'h1': 'v1'},success:function(data, statusText, xmlHttpRequest){alert(data);}})}</script></body>
</html>

HTML+JS

class CORSHandler(tornado.web.RequestHandler):# 复杂请求方法putdef put(self):self.set_header('Access-Control-Allow-Origin', "http://tkq1.com:8000")self.write('put success')# 预检方法设置def options(self,*args, **kwargs):#设置预检方法接收源self.set_header('Access-Control-Allow-Origin', "http://tkq1.com:8000")#设置预复杂方法自定义请求头h1和h2self.set_header('Access-Control-Allow-Headers', "h1,h2")#设置允许哪些复杂请求方法self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")#设置预检缓存时间秒,缓存时间内发送请求无需再预检self.set_header('Access-Control-Max-Age', 10)

c、跨域获取响应头

默认获取到的所有响应头只有基本信息,如果想要获取自定义的响应头,则需要再服务器端设置Access-Control-Expose-Headers。

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><h1>CORS</h1><input type="button" οnclick="XhrGetRequest();" value="put发送请求js" /><input type="button" οnclick="JqSendRequest();" value="put发送请求jq" /><script type="text/javascript" src='{{static_url("jquery-2.1.1.min.js")}}'></script><script type="text/javascript">functionXhrGetRequest(){var xhr =newXMLHttpRequest();xhr.onreadystatechange= function(){if(xhr.readyState == 4){var data =xhr.responseText;alert(data);//获取响应头
console.log(xhr.getAllResponseHeaders());}};xhr.open('put', "http://tkq2.com:8000/cors", true);xhr.setRequestHeader('h1', 'v1');xhr.send();}functionJqSendRequest(){$.ajax({url:"http://tkq2.com:8000/cors",type:'PUT',dataType:'text',headers: {'h1': 'v1'},success:function(data, statusText, xmlHttpRequest){alert(data);//获取响应头    Content-Type: text/html; charset=UTF-8  Cos2: cos_value2    Cos1: cos_value1
console.log(xmlHttpRequest.getAllResponseHeaders());}})}</script></body>
</html>

HTML+JS

class CORSHandler(tornado.web.RequestHandler):# 复杂请求方法putdef put(self):self.set_header('Access-Control-Allow-Origin', "http://tkq1.com:8000")# 自定义headerself.set_header('cos1', "cos_value1")self.set_header('cos2', "cos_value2")#设置允许请求端接收自定义的请求头,否则请求段无法接收自定义的请求头self.set_header('Access-Control-Expose-Headers', "cos1,cos2")self.write('put success')# 预检方法设置def options(self,*args, **kwargs):self.set_header('Access-Control-Allow-Origin', "http://tkq1.com:8000")self.set_header('Access-Control-Allow-Headers', "h1,h2")self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")self.set_header('Access-Control-Max-Age', 10) 

d、跨域传输cookie

在跨域请求中,默认情况下,HTTP Authentication信息,Cookie头以及用户的SSL证书无论在预检请求中或是在实际请求都是不会被发送。

如果想要发送:

  • 浏览器端:XMLHttpRequest的withCredentials为true
  • 服务器端:Access-Control-Allow-Credentials为true
  • 注意:服务器端响应的 Access-Control-Allow-Origin 不能是通配符 *(包括options方法)

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title>
</head>
<body><h1>CORS</h1><input type="button" οnclick="XhrGetRequest();" value="put发送请求js" /><input type="button" οnclick="JqSendRequest();" value="put发送请求jq" /><script type="text/javascript" src='{{static_url("jquery-2.1.1.min.js")}}'></script><script type="text/javascript">functionXhrGetRequest(){var xhr =newXMLHttpRequest();xhr.onreadystatechange= function(){if(xhr.readyState == 4){var data =xhr.responseText;alert(data);}};xhr.withCredentials= true;//允许跨域发送cookiesxhr.open('put', "http://tkq2.com:8000/cors", true);xhr.send();}functionJqSendRequest(){$.ajax({url:"http://tkq2.com:8000/cors",type:'PUT',dataType:'text',xhrFields:{withCredentials:true},//允许跨域发送cookiessuccess: function(data, statusText, xmlHttpRequest){alert(data);}})}</script></body>
</html>

HTML+JS

class CORSHandler(tornado.web.RequestHandler):# 复杂请求方法putdef put(self):self.set_header('Access-Control-Allow-Origin', "http://tkq1.com:8000")# 设置允许跨域传输cookieself.set_header('Access-Control-Allow-Credentials','true')self.set_cookie('myck', 'c_value')self.write('put success')# 预检方法设置def options(self,*args, **kwargs):self.set_header('Access-Control-Allow-Origin', "http://tkq1.com:8000")self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")self.set_header('Access-Control-Max-Age', 10)#设置允许跨域传输cookieself.set_header('Access-Control-Allow-Credentials', 'true')

转载于:https://www.cnblogs.com/tkqasn/p/5869175.html

AJAX请求和跨域请求详解(原生JS、Jquery)相关推荐

  1. 原生JS实现Ajax和JSONP跨域请求

    背景: 对接身份证录入和门锁卡号录入设备中,安装驱动完成后,提供的接口服务是http://localhost:8099/?cmd=readbcardid&charset=gbk,返回的数据格式 ...

  2. JQuery - Ajax和Tomcat跨域请求问题解决方法!

    JQuery - Ajax和Tomcat跨域请求问题解决方法! 参考文章: (1)JQuery - Ajax和Tomcat跨域请求问题解决方法! (2)https://www.cnblogs.com/ ...

  3. Ajax的Post跨域请求

    Ajax的Post跨域请求 什么是跨域请求 同协议,同ip,同端口视为一个域,两个域之间互相访问就是跨域访问请求. 根据浏览器的同源策略,一个域中的脚本只具有访问本域资源的权限,无法访问其他域的资源. ...

  4. jQuery中getJSON跨域原理详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp28 jQuery中getJSON跨域原理详解 前几天我再开发一个叫 河蟹工 ...

  5. proxytable代理不生效_proxyTable代理跨域使用详解

    这次给大家带来proxyTable代理跨域使用详解,proxyTable代理跨域使用的注意事项有哪些,下面就是实战案例,一起来看一下. 什么是代理跨域 浏览器之间有同源策略,出于安全考虑不同域之间不允 ...

  6. 关于web项目跨域问题详解

    一.为什么会出现跨域问题 出于浏览器的同源策略限制.同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响. ...

  7. php滚动窗口多条动态,详解原生JS是实现控制多个滚动条同步跟随滚动

    本文主要和大家详解详解原生JS是实现控制多个滚动条同步跟随滚动,当这两个容器元素的内容都超出了容器高度,即都出现了滚动框的时候,如何在其中一个容器元素滚动时,让另外一个元素也随之滚动. 在一些支持用 ...

  8. jsonp 跨域原理详解

    转载至:http://zha-zi.iteye.com/blog/1975116 JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制 ...

  9. web开发的跨域问题详解

    2019独角兽企业重金招聘Python工程师标准>>> 本文由云+社区发表 做过 web 开发的同学,应该都遇到过跨域的问题,当我们从一个域名向另一个域名发送 Ajax 请求的时候, ...

最新文章

  1. C++派生类与基类构造函数调用次序
  2. 关于mysql engine(引擎)的疑问
  3. 【转载】浅析输入法原理
  4. 多项新政催生本年度购房最佳“窗口期”
  5. Flash、Ajax各自的优缺点,在使用中如何取舍?
  6. [转]C++编译链接过程详解
  7. 路由器无线模式与信道检测
  8. 诚之和:一年过去了,蚂蚁集团IPO“批文”到期!再上市需重新“排队”
  9. 跨境公路货运调研分析-市场规模、市场份额、市场定位、产品类型以及发展规划
  10. 2022中元节前后几天不出门?前三天后三天不能出门是真的吗?
  11. 神箭手 爬虫操作(1)
  12. Android开发笔记(一百四十八)自定义输入法软键盘
  13. 高新技术企业申报认定需要满足哪些条件?
  14. 安卓隐藏摄像_隐藏拍摄app
  15. 计算机在生态文明建设的改造,关于中国生态文明建设的现状与未来思考
  16. 飞信2010分析 – SSI登录
  17. 主流相机镜头分析与代表作
  18. [行为识别论文详解]TSN(Temporal Segment Networks)
  19. linux中如何使用nginx部署多个静态资源文件?
  20. 【kafka】kafka乱码问题

热门文章

  1. css屏幕大小的容器,位置2箭头固定到CSS页面容器的外部 - 屏幕大小
  2. mysql for centos下载_python数据分析之路——centos下载并配置mysql与navicat的使用
  3. 创建面板对象Java,从PNG图像或Java面板创建PDF
  4. 腾讯云【人脸识别】服务的一次尝试(JAVA)
  5. JAVA连接 mongodb(mac OSX)
  6. 软件项目管理0713:三级等保的重要性
  7. 审计 Linux 系统的操作行为的 5 种方案对比
  8. MapReduce Java API-多输入路径方式
  9. CentOS7上搭建Hadoop集群(入门级)
  10. ElementUI中的el-table实现递增的序号列