前后端交互

389 阅读5分钟

前后端交互

ajax

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),

​ 是指一种创建交互式、快速动态网页应用的网页开发技术,

​ 无需重新加载整个网页的情况下,能够更新部分网页的技术。

通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。

这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

ajax优缺点

优点

  • 在不更新整个页面的前提下维护数据
  • Web应用程序更为迅捷的回音用户动作,避免在网络上发送那些没有改变的信息
  • ajax不用插件,允许用户使用js在浏览器上运行

缺点

破坏回退
  • 动态更新新页面的情况下,用户无法回退到前一个页面或状态(浏览器只能记录静态页面)
  • 解决方法
    • H5之前通过点击后退按钮访问历史记录时候,通过创建或使用一隐藏的IFRAME来重现页面上的变更
    • eg:用户在Google Maps中单击后退时,它在一个隐藏的IFRAME中进行搜索,然后将搜索结果反映到Ajax元素上,以便将应用程序状态恢复到当时的状态
破坏收藏功能
  • H5之前使用一种方式是使用URL片段辨识符(通常称为锚点,及URL#锚点)来保持追踪,允许用户回到某个状态
  • H5之后可以直接操作浏览你是,并以字符串存储网页状态,将网页加入收藏夹或书签会被隐形地保留
网络延迟问题
  • 网络延迟:即用户发出请求到服务器发出响应之间的间隔(可以通过加一个时间定时器来实现,设置一个时间间隔来)
安全问题
  • ajax源码是可读的
  • 攻击者可以将脚本插入系统

ajax初体验

运行环境

需要运行到网络服务器上,例如node,tomcat等

运行原理

  • 前者开发人员不可控

  • 后者开发人员可以控制

实现步骤

demo1

//创建Ajax对象
var xhr  = newXMLHttpRequest();
//告诉Ajax请求地址以及请求方式
xhr.open('get','http://www.example.com');
//发送请求
xhr.send();
//获取服务器端给客户端的响应数据
xhr.onload = function(){
  console.log(xhr.responseText);
}

demo2

var xmlhttp;

if (window.XMLHttpRequest){
  //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
  xmlhttp=new XMLHttpRequest();
}
else{
  // IE6, IE5 浏览器执行代码
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
  if (xmlhttp.readyState==4 && xmlhttp.status==200){
    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
  }
}
xmlhttp.open('get','http://www.example.com');
xmlhttp.send();
//获取服务器端给客户端的响应数据
xmlhttp.onload = function(){
  console.log(xhr.responseText);
} 
属性 描述
onreadystatechange readyState属性发生改变后触发
readyState 0: 请求未初始化 1: 服务器连接已建立 2: 请求已接收 3: 请求处理中 4: 请求已完成,且响应已就绪(只有4是完全成功的)
status 200:"OK" 404: 未找到页面

4种常见的ajax请求方式

jquery还封装了jsonp在ajax里面,可以解决跨域问题

$.ajax()

$.ajax({
  type: "post",//可以选get或post
  dataType: "json",//指定服务器返回正确的数据格式
  url: 'http://www.example.com',
  data: { name: "John", sex: "man" },
  success: function (data) {
    if (data != "") {
      console.log(data);
     }
  }
});

$.get()

通过HTTP GET请求载入信息

$.get("http://www.example.com", { name: "John", sex: "man" },
  function(data){
  alert("Data Loaded: " + data);
});

$.post()

通过HTTP POST请求载入数据

$.post("http://www.example.com", { name: "John", sex: "man" }, 
  function (data) {
  if (data == "ok") {
   	 alert("添加成功!");
 	 }
})

$getJOSN()

请求载入JSON数据

$.getJSON("http://www.example.com",
function(data){
	console.log(data);
});

fetch()

developer.mozilla.org/zh-CN/docs/…

  • fetch api 是基于Promise设计,旧浏览器不支持Promise, 需要使用pollyfill es6-promise

  • fetch不接受跨域cookie

  • fetch不会发送cookie

fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });
postData('http://example.com/answer', {answer: 42})
  .then(data => console.log(data)) // JSON from `response.json()` call
  .catch(error => console.error(error))

function postData(url, data) {
  // Default options are marked with *
  return fetch(url, {
    body: JSON.stringify(data), // must match 'Content-Type' header
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, same-origin, *omit
    headers: {
      'user-agent': 'Mozilla/4.0 MDN Example',
      'content-type': 'application/json'
    },
    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, cors, *same-origin
    redirect: 'follow', // manual, *follow, error
    referrer: 'no-referrer', // *client, no-referrer
  })
  .then(response => response.json()) // parses response to JSON
}

axios

axios-js.com/zh-cn/docs/

一个基于promise的HTTP库,可以用在浏览器和node.js中

使用

使用 npm:

$ npm install axios

使用 bower:

$ bower install axios

使用 cdn:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

特性

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

axios初体验

执行GET请求

// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// 上面的请求也可以这样做
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

执行POST请求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

执行多个并发请求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }))

axios API

// 发送 POST 请求
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});
// 获取远端图片
axios({
  method:'get',
  url:'http://bit.ly/2mTM3nY',
  responseType:'stream'
})
  .then(function(response) {
  response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});

promise封装axios

  • promise处理异步的方法

  • vue项目中封装方法放在utils文件夹里

/* eslint-disable no-unused-vars */
import axios from 'axios';
let baseURL;
if(process.env.NODE_ENV=='development'){
    baseURL = 'http://132.232.94.151:3000/api'
}else{
    baseURL = '/xxx'
}
// baseURL es6 方法


const $http = axios.create({
    baseURL,
})
// create 是axios自带的方法

export const get = (url,params)=>{
    params = params || {};
    return new Promise((resolve,reject)=>{
        // axiso 自带 get 和 post 方法
        $http.get(url,{
            params,
        }).then(res=>{
            if(res.data.status===0){
                resolve(res.data);
            }else{
                alert(res.data.msg)
            }
        }).catch(error=>{
            alert('网络异常');
        })
    })
}

export const post = (url,params)=>{
    params = params || {};
    return new Promise((resolve,reject)=>{
        $http.post(url,params).then(res=>{
            if(res.data.status===0){
                resolve(res.data);
            }else{
                alert(res.data.msg);
            }
        }).catch(error=>{
            alert('网络异常');
        })
    })
}

main.js

import { get, post } from "./utils/index";
Vue.prototype.$http = {
  get,
  post
};

created() {
    this.getData();
  },
  methods: {
    async getData() {
      const url = ";
      // 要访问第二页的话在网址后面加 ?type=2&pageNum=页数
      const res = await this.$http.get(url);//因为是promise对象要使用async 函数(){ await 数据} 因为promise是异步方法
      this.data = res.data;
    },