跨域 文件上传 jquery ajax

FormData 对象

  1. 模拟HTML表单, 相当于将 HTML 表单映射成表单对象, 自动将表单对象中的数据拼接成请求参数的格式
  2. 异步上传二进制文件

准备表单内容

<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 滚动条三方库

https://github.com/rstacruz/nprogress

// jquery 中只能给 document 注册事件触发
$(document).on('ajaxStart', function () {
    // 请求开始发送时触发
    NProgress.start()
})
$(document).on('ajaxComplete', function () {
    // 请求结束后触发
    NProgress.done()
})
// 如果需要自定义样式可以在css样式中手动修改 或者采用层级覆盖的方式进行修改
posted @ 2020-05-07 21:23  计算机相关人员  阅读(825)  评论(0编辑  收藏  举报