跨域 文件上传 jquery ajax
FormData 对象
- 模拟HTML表单, 相当于将 HTML 表单映射成表单对象, 自动将表单对象中的数据拼接成请求参数的格式
- 异步上传二进制文件
准备表单内容
<form id="form">
<input type="input" name="username" />
<input type="input" name="password" />
<input type="button" name="submit" />
</form>
实例化 formData 构造函数
var formData = new FormData(form)
发送请求; 只能传入到 send 方法中, 只适用于 表单传输的 post 请求
xhr.send(formData)
FormData 实例方法
-
获取表单中属性的值
-
formData.get('key')
-
-
设置表单中属性的值, 设置的存在会替换原有的值, 如果不存在就新建
-
formData.set('key', 'value')
-
-
删除表单对象中属性的值
-
formData.delete('key', 'value')
-
-
向表单对象中追加值
-
formData.append('key', 'value')
-
**注意 : **set 与 append 方法的区别是 , 再属性名已存在的情况下 , set 会覆盖, append 会保留两个值
FormData 上传二进制文件
文件选择控件
var file = document.getElementById('file');
// 获取进度条元素
var bar = document.getElementById('bar');
// 获取图片容器
var box = document.getElementById('box');
// 为文件选择控件添加onchanges事件
// 在用户选择文件时触发
file.onchange = function () {
var formData = new FormData()
// this.files[0] 是一个集合, 默认情况下只能传递一个文件所以会 files[0]
formData.append('attrName', this.files[0])
var xhr = new XMLHttpRequest()
xhr.open('post', 'http://admin.fungoweb.com/api/upload/osstoken')
xhr.upload.onprogress = function (ev) {
// ev.loaded // 已经上传多少
// ev.total // 文件总大小
var result = (ev.loaded / ev.total) * 100 + '%'
bar.style.width = result
bar.innerHTML = result
}
xhr.send(formData)
xhr.onload = function () {
if (xhr.status === 200) {
console.log(xhr.responseText)
}
}
}
同源政策
ajax 只能向自己的服务器发送请求,
什么是同源 : 如果两个页面用于相同的协议 , 域名, 端口, 那么这两个页面就属于同一个源
同源政策的目的
为了用户信息的安全, 防止恶意的网站盗窃数据, 最初的同源政策是指A网站在客户端设置 cookie , B网站是不能访问的
使用 JSONP 解决同源限制问题
jsonp 是 json with padding 的缩写, 它不属于 ajax 请求, 但是可以模拟 ajax 请求 需要前后端配合
将不同服务器请求地址写到script标签的src中
<script src="http://localhost:3000/test"></script>
服务端的响应必须是一个函数的调用, 真正要发送给客户端的数据需要作为函数调用的参数
const data = 'fn({username: "zs"})'
res.send(data)
在客户端的全局作用域下定义函数 fn
function fn(data) {}
在函数内部对服务器返回的数据进行处理
function fn(data) {console.log(data)}
CORS 跨域资源共享
全称 Cross-origin resource sharing 即跨域资源共享, 它允许浏览器向跨域服务器发送 ajax 请求, 克服了 ajax 只能同源使用的限制 此方法只需要服务端在响应头包含 Access-Control-Access-Origin
Access-Control-Access-Origin: 'http://localhost:3000'
Access-Control-Access-Origin: '*' // 代表谁都能访问
服务端访问非同源解决方案
同源政策是浏览器给予ajax技术的限制 , 服务端是不存在同源政策限制的;
可以使用 node 作为中台 , 请求其他的数据, 然后返回给 页面来操作 ;
node 请求第三方接口需要依赖第三方模块 request 包
npm install request --save
withCredentials 属性
在使用 ajax 技术发送跨域请求时, 默认情况下不会在请求中携带 cookie 信息
withCredentials : 指定在涉及跨域请求时是否携带 cookie 信息, 默认为 false
Access-Control-Allow-Credentials: true 允许客户端发送请求时携带cookie
// 客户端 javascript
xhr.open('post', 'http://localhost:3001/login')
xhr.widthCredentials = true // 当发送跨域请求时,携带cookie信息
// 服务端 Node.js
res.header('Access-Control-Allow-Credentials', true);
jQuery Ajax 请求
// get 请求
$.ajax({
type: 'get',
url: 'https://www.fungoweb.com/api/portal/system/circle/event/homePage',
// 不管请求是 post 还是 get 默认都是form data 传输 ?page=1&limit=10
data: {
page: 1,
limit: 10
},
// 成功返回请求结果
success: function (result) {
console.log(result)
},
// 失败返回失败对象
error: function (xhr) {
console.log(xhr)
}
})
// post 请求
$.ajax({
type: 'post',
url: 'https://www.fungoweb.com/api/portal/games/get/games',
// 如果想要传输 json 格式数据, 需要指定请求头
contentType: 'application/json;charset=utf8',
// 并且传入字符串形式的对象
data: JSON.stringify({
page: 1,
limit: 10
}),
beforeSend: function () {
// brforeSend 请求发送之前的触发的函数
console.log('beforeSend')
// return false 阻止代码向下执行
return false
},
success: function (result) {
console.log(result)
},
error: function (xhr) {
console.log(xhr)
}
})
get post
$('.btn1').on('click', function () {
$.get('https://www.fungoweb.com/api/portal/system/circle/event/homePage',{
page: 1,
limit: 10
},
function (response) {
console.log(response)
})
})
$('.btn2').on('click', function () {
$.post('https://www.fungoweb.com/api/portal/games/get/games', {
page: 1,
limit: 10
},
function (response) {
console.log(response)
})
})
serialize()
serialize 可以获取表单中所有选项的值, 并且拼接成 form data 的格式
$(function () {
$('#form').on('submit', function () {
// username=admin&password=123456
console.log($(this).serialize())
return false // 阻止表单的默认提交
})
})
Ajax 全局事件
只要页面中有Ajax请求被发送, 对应的全局事件就会被触发
nprogress 滚动条三方库
// jquery 中只能给 document 注册事件触发
$(document).on('ajaxStart', function () {
// 请求开始发送时触发
NProgress.start()
})
$(document).on('ajaxComplete', function () {
// 请求结束后触发
NProgress.done()
})
// 如果需要自定义样式可以在css样式中手动修改 或者采用层级覆盖的方式进行修改