web开发之数据交互

一、Ajax

在网页中利用XMLHttpRequest 对象与服务器进行数据交互的方式,就是Ajax。

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

  • 接口

使用Ajax请求数据时,被请求的URL地址,就叫做数据接口(简称接口)。同时,每个接口必须有请求方式。

使用strapi创建接口https://getstrapi.cn/developer-docs/latest/setup-deployment-guides/installation.html

(一)实现方式

1.XMLHttpRequest对象

老版本的 Internet Explorer(IE5 和 IE6)使用 ActiveX 对象:

variable = new ActiveXObject("Microsoft.XMLHTTP");

为了应对所有浏览器,包括 IE5 和 IE6,请检查浏览器是否支持 XMLHttpRequest 对象。如果支持,创建 XMLHttpRequest 对象,如果不支持,则创建 ActiveX 对象:

var xhttp;
if (window.XMLHttpRequest) {
    xhttp = new XMLHttpRequest();
    } else {
    // code for IE6, IE5
     xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
  • 查询字符串

查询字符串(URL参数)是指在URL的末尾加上用于向服务器发送信息的字符串(变量)。

格式:将英文的?放在URL的未尾,然后再加上参数=值,想加上多个参数的话,使用&符号进行分隔。

http: / / wwwa.liulongbin.top : 3006/ apilgetbooks?id=1

  • url编码

URL地址中,只允许出现英文相关的字母、标点符号、数字,因此,在URL地址中不允许出现中文字符。如果URL中需要包含中文这样的字符,则必须对中文字符进行编码(转义)

URL编码原则的通俗理解:使用英文字符去表示非英文字符。

http: / / www .liulongbin.top: 3006/api/getbooks?id=1sbookname=西游记//经过URL编码之后,URL地址变成了如下格式:
http:// ww.liulongbin.top:3006/api/getbooks?id=16bookname=8E89A58BF号E68B8%B83E88AE%B0
  • 编码-encodeURL("")

  • 解码-decodeURL("")

(1)创建对象
variable=new XMLHttpRequest();
(2)请求

方法

描述

open(method,url,async)

规定请求的类型、URL 以及是否异步处理请求。method:请求的类型;GET 或 POST;url:文件在服务器上的位置async:true(异步)或 false(同步)

send(string)

将请求发送到服务器。string:仅用于 POST 请求

.onreadystatechange

监听事件

  • GET请求

xmlhttp.open("GET","/try/ajax/demo_get.php",true);
xmlhttp.send();

当使用 async=true 时,请规定在响应处于 onreadystatechange 事件中的就绪状态时执行的函数

xmlhttp.onreadystatechange=function(){
	//监听请求状态readystate 服务器响应的状态status
	if (xhr.readyState ==4 && xhr.status ==200){
		//数据获取成功
        return xhr.responseText;//字符串
	}
};
xmlhttp.open("GET","/try/ajax/ajax_info.txt",true);
xmlhttp.send();

//如果您希望通过 GET 方法发送信息,请向 URL 添加信息:
xmlhttp.open("GET","/try/ajax/demo_get2.php?fname=Henry&lname=Ford",true);
xmlhttp.send();
  • post请求

在以下情况中,请使用 POST 请求:

  • 不愿使用缓存文件(更新服务器上的文件或数据库)

  • 向服务器发送大量数据(POST 没有数据量限制)

  • 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

//如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据
xmlhttp.open("POST","/try/ajax/demo_post2.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Henry&lname=Ford");

方法

描述

setRequestHeader(header,value)

向请求添加 HTTP 头。header: 规定头的名称value: 规定头的值

//创建xhr对象
var xhr = new XMLHttpRequest()
//调用xhr.open函数
xhr.open("POST","")
//设置Content-Type属性
//调用xhr.send()函数,同时指定要发送的数据
xhr.send()
//监听xhr.onreadystatechange事件
xhr.onreadystatechange = function(){
	//监听请求状态readystate 服务器响应的状态status
	if (xhr.readyState ==4 && xhr.status ==200){
		//数据获取成功
        return this.xhr.responseText;//字符串
	}
}
(3)响应

如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。

属性

描述

responseText

获得字符串形式的响应数据。

responseXML

获得 XML 形式的响应数据。

document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
(4)事件
  • onreadystatechange 事件

当请求被发送到服务器时,我们需要执行一些基于响应的任务。

每当 readyState 改变时,就会触发 onreadystatechange 事件。

readyState 属性存有 XMLHttpRequest 的状态信息。

属性

描述

onreadystatechange

存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。

readyState

存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。0: 请求未初始化1: 服务器连接已建立2: 请求已接收3: 请求处理中4: 请求已完成,且响应已就绪

status

200: "OK" 404: 未找到页面

xmlhttp.onreadystatechange=function()
{
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
        document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
}

2.jquery中的Ajax

  • $.get()

专门用来发起get请求,从而将服务器上的资源请求到客户端来进行使用。

$.get (ur1,[data], [callback])

$.get("demo_test.php",function(data,status){
    alert("数据: " + data + "\n状态: " + status);
  });
  • URL:发送请求的 URL字符串。

  • data:可选的,发送给服务器的字符串或 key/value 键值对。

  • callback:可选的,请求成功后执行的回调函数。

  • $.post()

$.post( URL [, data ] [, callback ]

    $.post("/try/ajax/demo_test_post.php",
    {
        name:"菜鸟教程",
        url:"http://www.runoob.com"
    },
    function(data,status){
        alert("数据: \n" + data + "\n状态: " + status);
    });
  • URL:发送请求的 URL字符串。

  • data:可选的,发送给服务器的字符串或 key/value 键值对。

  • callback:可选的,请求成功后执行的回调函数。

  • $.ajax()

$.ajax ( {
	type: '',//请求的方式,例如GET或POST
	url: '',//请求的URL地址
	data: { },//这次请求要携带的数据
	success: function (res) {}//请求成功之后的回调函数
})
  • $.getJSON()

$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?",
function(data){
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#images");
if ( i == 3 ) return false;
});
});

(二)跨域与JSONP

1.同源

同源指的是两个URL的协议、域名、端口一致,反之,则是跨域。

同源策略(英文全称Same origin policy)是浏览器提供的一个安全功能。

MDN 官方给定的概念:同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

通俗的理解:浏览器规定,A网站的JavaScript,不允许和非同源的网站C之间,进行资源的交互,例如;

  • 无法读取非同源网页的Cookie.LocalStorage和IndexedDB

  • 无法接触非同源网页的DOM

  • 无法向非同源地址发送Ajax请求,

2.跨域

出现跨域的根本原因:浏览器的同源策略不允许非同源的URL之间进行资源的交互。

  • 浏览器对跨域请求的拦截

注意:浏览器允许发起跨域请求,但是,跨域请求回来的数据,会被浏览器拦截,无法被页面获取到!

  • 跨域数据请求

  • jsonp

只支持GET请求,不支持POST请求。

  • cors

3.JSONP

实现原理

由于浏览器同源策略的限制,网页中无法通过Ajax请求非同源的接口数据。但是 标签不受浏览器同源策略的影响,可以通过src属性,请求非同源的js 脚本。

//定义一个success回调函数:
<script>
	function success ( data) {
		console.log ( '获取到了data数据:')
        console.log(data)
	}
</script>
//通过<script>标签,请求接口数据:
<script src= "http:/lajax. frontend.itheima . net:3006/api/jsonp?callback=success&name=zs&age=20"</script>

二、axios

基于promise可以用于浏览器和node.js的网络请求库

  • 安装

npm install axios

(一)基础语法

axios({
    method:"请求类型",
    url:""
    //url中的查询参数 get
    params:{},
    //请求体参数  post
    data:{}
}).then((result)=>{
    //.then 请求成功后的回调函数
    //result 请求成功之后的结果
}).catch(function (error) {
    // 处理错误情况
    console.log(error);
  })
  .then(function () {
    // 总是会执行
  });

// 支持async/await用法
async function getUser() {
  
}
  • 结合async和await

async function(){
    //如果调用某个方法的返回值promise实例,则前面可以添加await
    //await 只能用在被async修饰的方法中
	let result=await axios({
    method:"请求类型",
    url:""
    params:{},//url中的查询参数 get
    data:{}//请求体参数  post
})
  • 使用解构赋值拿取真实数据(终极版)

async function(){
    
	try {
        //解构赋值的时候,使用:进行重命名
    	let {data:res}=await axios({
    	method:"请求类型",
    	url:""
    	//url中的查询参数 get
    	params:{},
    	//请求体参数  post
    	data:{}
  	} catch (error) {
    	console.error(error);
  }
})

(二)api

  • 请求配置

const request=axios.create({
  // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  // 自定义请求头
  headers: {'X-Custom-Header': 'foobar'}
});
  • 请求方式别名

axios.request(config)

axios.get(url[, config])

axios.delete(url[, config])

axios.head(url[, config])

axios.options(url[, config])

axios.post(url[, data[, config]])

axios.put(url[, data[, config]])

axios.patch(url[, data[, config]])

  • axios.get

const {data:res} = await axios.get("url",{
	params:{} //
})
  • axios.post

//发起一个 POST 请求
axios.post("url",
           {}//请求体数据
          )



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');
}

Promise.all([getUserAccount(), getUserPermissions()])
  .then(function (results) {
    const acct = results[0];
    const perm = results[1];
  });
  • 把axios挂载到vue原型上

//main.js
import axios from "axios"
axios.defaults.baseURL='请求根路径'
Vue.prototype.$html = axios
//其他组件使用
const {data:res} =await this.$html.get(“/api”)
缺点:api无法复用
  • 推荐方案

//utils/request.js  axios进一步封装
import axios from 'axios'

const request = axios.create({
    //指定请求的根路径
    baseURL:''
})

export default  request
  • 上传图片

注:这里是strapi创建的接口

  • 获取图片的数据结构

{name: '2023-01-30_172645.png', lastModified: 1675071175456, lastModifiedDate: Mon Jan 30 2023 17:32:55 GMT+0800 (中国标准时间), webkitRelativePath: '', size: 303379, …}
  • 方法

//图片上传,结合change事件
function uploadImg(e) {
  const formData = new FormData(); //formData对象
  // console.log(e.target.files[0]); 
  const file = e.target.files[0]; //图片文件
  formData.append("files", file);
  // 上传接口,需要在public中开启upload的权限
  axios
    .post("http://strapi.imqd.cn:1337/api/upload", formData)
    .then((response) => {
      //after success
      console.log(response);
      this.tempPicId = response.data[0].id;  //返回图片在后台的id号,后续用
    })
    .catch((error) => {
      //handle error
      console.log(error);
    });
}
//表单数据
function createCt() {
  axios
    .post("http://strapi.imqd.cn:1337/api/cantings", {
      data: {
        title: this.cttitle,
        phone: this.phone,
        thumb: this.tempPicId || 26, //图片字段,如果用户没有选择图片,则默认用id为26的图片(暂无图片)
      },
    })
    .then(function (response) {
      // console.log(response);
      alert("创建成功!");
      form.value = {
        cttitle: "",
        phone: "",
      };
      // 每次更新后,需要调用更新列表
      getList();
    })
    .catch(function (error) {
      console.log(error);
    });
}
  • axios.put

axios
      .put("http://strapi.imqd.cn:1337/api/cantings/" + id, {
        data: {
          id: id,
          title: title,
          yunfei: false,
          rate: 5,
        },
      })
      .then(function (response) {
        // console.log(response);
        alert("更新成功!");
        // 每次更新后,需要调用更新列表
        getList();
      })
      .catch(function (error) {
        console.log(error);
        alert("更新失败!");
      });
  • axios.delete

axios
      .delete("http://strapi.imqd.cn:1337/api/cantings/" + id)
      .then(({ data }) => {
        // console.log(res);
        if (data) {
          alert("删除成功");
          // 刷新列表
          getList();
        } else {
          alert("删除失败");
        }
      })
      .catch((err) => {
        console.log("删除失败");
      });

(三)响应结构

一个请求的响应包含以下信息。

{
  // `data` 由服务器提供的响应
  data: {},

  // `status` 来自服务器响应的 HTTP 状态码
  status: 200,

  // `statusText` 来自服务器响应的 HTTP 状态信息
  statusText: 'OK',

  // `headers` 是服务器响应头
  // 所有的 header 名称都是小写,而且可以使用方括号语法访问
  // 例如: `response.headers['content-type']`
  headers: {},

  // `config` 是 `axios` 请求的配置信息
  config: {},

  // `request` 是生成此响应的请求
  // 在node.js中它是最后一个ClientRequest实例 (in redirects),
  // 在浏览器中则是 XMLHttpRequest 实例
  request: {}
}
  • 错误

  • "status": 400, 该传的参数没能传递到后端。

{
    "data": null,
    "error": {
        "status": 400,
        "name": "ValidationError",
        "message": "Missing \"data\" payload in the request body",
        "details": {}
    }
}

//解决方法
使用get模式 查询数据的格式,例如是否用data:{}进行封装了
{"data":[{"id":1,"attributes":{"foot_name":"黄河大鲤鱼","price":100,"createdAt":"2023-02-18T08:31:30.208Z","updatedAt":"2023-02-18T08:31:31.760Z","publishedAt":"2023-02-18T08:31:31.758Z"}]}
  • "status": 500,一般是post参数值出现错误,应仔细检查各个参数值

三、Json-数据交换

(一)定义

  • 数据交换格式,就是服务器端与客户端之间进行数据传输与交换的格式。

  • JSON就是Javascript对象和数组的字符串表示法,它使用文本表示一个JS对象或数组的信息,因此,JSON的本质是字符串

  • JSON 是轻量级的文本数据交换格式

(二)结构

JSON就是用字符串来表示Javascript 的对象和数组。所以,JSON中包含对象和数组两种结构,通过这两种结构的相互嵌套,可以表示各种复杂的数据结构。

  • 对象结构:对象结构在JSON 中表示为{}括起来的内容。数据结构为{ key: value, key: value,...}的键值对结构。其中,key必须是使用英文的双引号包裹的字符串,value的数据类型可以是数字、字符串、布尔值、null、数组、对象6种类型。

{
	"key":value
}
//字符串必须是双引号
//JSON中不能写注释
//JSON的最外层必须是对象或数组格式
{
	"name":"mfm",
	"age":20,
	"gender":"男",
	"address":null,
	"hobby":[]
}
  • 数组结构:数组结构在JSON中表示为[]括起来的内容。数据结构为["java" , javascript ,30, true...].数组中数据的类型可以是数字、字符串、布尔值、null、数组、对象6种类型

(三)JSON和JS对象的关系

JSON是JS对象的字符串表示法,它使用文本表示一个JS对象的信息,本质是一个字符串。例救如:

//这是一个对象
var obj = {a: 'Hello', b: 'world'}
//这是一个JSON字符串,本质是一个字符串
var json = ' { "a" : "Hello","b":world"}'

(四)JSON和JS对象的互转

  • JSON.parse()-反序列化

使用 JSON.parse() 方法将数据转换为 JavaScript 对象

JSON.parse(text[, reviver]);
  • JSON.stringify()-序列化

使用 JSON.stringify() 方法将 JavaScript 对象转换为字符串。

JSON.stringify(value[, replacer[, space]])

(五)常见错误

原因:请求头错误或没有请求头

措施:在浏览器-f12-网络-xhr找数据-表头-请求头

$.ajax({
        type: "GET",
        url: MAIN_URL,
        data: {
            cityId: 110100,
            pageNum: 1,
            pageSize: 10,
            type: 1,
            k: 5777825
        },
        headers: {
            'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16623432381623158335471617","bc":"110100"}',
            'X-Host': 'mall.film-ticket.film.list'
        },
        success:function(res){
            cb(res)
        },
        error:function(err){
            cb(err)
        }
    })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨非墨Lg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值