<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- CORS 跨域资源共享
CORS:全称 Cross-origin resource sharing,
即跨域资源共享,它允许浏览器向跨域服务器发送ajax请求,
json是直接绕过同源限制了,CORS是允许,CORS克服了ajax只能同源使用的限制
-->
<button id="btn">点击发送请求</button>
<script src="./ajax.js"></script>
<script>
var btn = document.querySelector('#btn')
btn.addEventListener('click', function () {
ajax({
type: 'get',
url: 'http://localhost:3001/cross',
success: function (data) {
console.log(data);
}
})
})
</script>
<!--(node) 服务器端写法,在响应头中拦截所有请求
app.use((req, res, next) => {
// 允许那些客户端访问我
res.header('Access-Control-Allow-Origin', '*') // * 代表允许所有客户端访问我
// 允许客户端使用那些请求方法访问我
res.header('Access-Control-Allow-Methods', 'get,post')
next()
})
app.get('/cross', (req, res) => {
res.send('ok')
}) -->
</body>
</html>
./ajax.js
function ajax(options) {
// 存储默认值,有些用户没有传,就使用默认值
var defaults = {
//请求方式
type: 'get',
// 请求地址
url: '',
data: {},
Headers: {
'content-type': 'application/x-www-form-urlencoded'
},
success: function (data) {},
error: function (data, xhr) {}
}
// 对象覆盖,如果用户传了。就要用 用户的
// 使用options对象中的属性,覆盖defaults中的数据
// assign会影响原对象
Object.assign(defaults,options)
var xhr = new XMLHttpRequest()
// 拼接请求参数的变量
var params = ''
// 循环用户传递的对象参数,get方法的拼接
for (var attr in defaults.data) {
// 将参数转换为字符串格式
params += attr + '=' + defaults.data[attr] + '&'
}
// 在参数最后面会有一个'&'符号,需要截取
params = params.substr(0, params.length - 1)
// 判断请求方式 get还是post
if (defaults.type == 'get') {
defaults.url = defaults.url + '?' + params
}
xhr.open(defaults.type, defaults.url)
if (defaults.type == 'post') {
// 这里将content-Type 写死了,是不合理的,有时候可能会传递json类型数据
// 这里应该是调用函数的人传递
// xhr.setRequestHeader('Content-Type','application/x-www-urlencoded')
// 注意如果带了 '-' 这个符号,如果这个横线不是一个字符串在JavaScript中就不是合法的
// options.Headers['content-type'] 这样才合法,可以把它当做一个变量存储
// 客户端希望向服务器端传递的数据格式
var contentType = defaults.Headers['content-type']
xhr.setRequestHeader('Content-Type', contentType)
//这里就对传递的数据格式进行判断
// 如果是json格式,需要转化为字符串
if (contentType == 'application/json') {
xhr.send(JSON.stringify(defaults.data))
} else {
xhr.send(params)
}
} else {
xhr.send()
}
xhr.send()
xhr.onload = function () {
// xhr.getResponseHeader() 获取响应头中的数据,返回一个字符串
// 判断数据类型,判断返回的字符串中是否包含application/json等
var contentType = xhr.getResponseHeader('Content-Type')
// 把服务器端返回的数据存储起来
var responseText = xhr.responseText
if (contentType.includes('application/json')) {
// 将服务器端的json数据装换为json对象
responseText = JSON.parse(responseText)
}
// 状态成功
if (xhr.status == 200) {
defaults.success(responseText, xhr)
// 服务器端一般返回的是json数据格式,
// 服务器端会在请求头返回数据格式
} else {
//传递错误信息,把xhr返回,xhr包含的信息更多
defaults.error(responseText, xhr)
}
}
}