HTTP 协议、前端后端交互技术详解

目录

HTTP 协议、前端后端交互技术详解

一、HTTP 协议基础

(一)请求报文

(二)响应报文

(三)状态码

二、请求参数相关

(一)Query String 参数

(二)GET 与 POST 请求区别

三、Node.js 相关

(一)安装与检测

(二)http 模块使用

四、Express 框架使用

(一)安装与初始化

(二)使用步骤

五、Nodemon 工具

六、AJAX 技术

(一)使用 XMLHttpRequest 对象发送请求步骤

(二)JSONP 解决跨域(仅适用于 GET 请求)

(三)CORS 解决跨域

七、Axios 使用

(一)特点

(二)安装

(三)基本使用

(四)Vue 中使用 Axios

八、其他要点

(一)URL 编码

(二)跨域概念


        在前端与后端的交互过程中,HTTP 协议起着核心作用,同时多种技术协同实现数据的请求与响应。下面将对相关技术进行详细阐述。

一、HTTP 协议基础

HTTP(HyperText Transfer Protocol)是浏览器与服务器通信的协议,它规定了请求和响应的格式。

(一)请求报文

  1. 请求行:包含请求方法(如 GET、POST 等)、请求路径和协议版本,例如post /index.html HTTP/1.1 。GET 请求主要用于获取资源,其参数会直接附加在 URL 后面;POST 请求则常用于提交数据,参数位于请求体中。
  2. 请求头:携带请求的相关信息,像请求资源的域名(Host)、端口、HTTP 版本、浏览器类型、语言、编码、缓存控制、内容类型等。这些信息有助于服务器理解请求的上下文,例如Content-Type字段用于告知服务器请求体的数据类型。
  3. 空行:用于隔离请求头和请求体,虽然看似简单,但在 HTTP 协议中是必不可少的分隔标识。
  4. 请求体:GET 请求时,请求体为空;POST 请求时,请求体可包含表单数据、JSON 数据等内容。例如在用户登录场景中,POST 请求体可包含用户名和密码。

(二)响应报文

  1. 响应行:由协议版本、状态码和状态描述组成,如HTTP/1.1 200 OK 。状态码是服务器对请求处理结果的重要标识,不同的状态码代表不同的含义。
  2. 响应头:包含响应的相关信息,如内容类型(Content-Type)、内容长度、日期、服务器信息等。Content-Type指定了响应体的数据类型,比如text/html表示 HTML 页面,application/json表示 JSON 数据。
  3. 空行:隔离响应头和响应体,确保协议格式的规范性。
  4. 响应体:服务器返回的结果,例如 HTML 页面内容<html>...</html> ,或者 JSON 格式的数据{"message": "success"} 。

(三)状态码

  1. 200 OK:表示请求成功,这是最常见的成功状态码,意味着服务器已成功处理请求并返回了相应数据。
  2. 404 Not found:请求的资源不存在,当用户访问一个不存在的页面或文件时,服务器会返回此状态码。
  3. 403 Forbidden:禁止访问,通常是由于用户没有足够的权限访问请求的资源。
  4. 401 Unauthorized:未授权访问,一般是因为用户未提供有效的身份验证信息。
  5. 400 Bad Request:错误的请求,可能是由于请求格式不正确、参数缺失或错误等原因导致。
  6. 500 Internal Server Error:服务器内部错误,这是服务器端出现了未预料到的错误情况。

通过浏览器控制台的 Network 选项,可以查看 HTTP 请求的详细过程,包括请求头、请求体、响应头和响应体等信息。这对于调试和分析前端与后端的交互非常有帮助。

二、请求参数相关

(一)Query String 参数

在 URL 中,参数以?key=value的形式添加,多个参数用&分隔,例如http://www.example.com/index.html?name=john&age=25 。在请求头中,参数以key:value的形式存在,如Host: www.example.com 、Content-Type: application/x-www-form-urlencoded 。这种参数传递方式简单直观,常用于向服务器请求特定资源。

(二)GET 与 POST 请求区别

  1. 参数位置:GET 请求参数在 URL 中,POST 请求参数在请求体中。这使得 GET 请求的参数可见,而 POST 请求的参数相对隐蔽。
  2. 数据量限制:GET 请求受 URL 长度限制,不能发送大量数据;POST 请求无此限制,适合发送大量数据,如文件上传。
  3. 功能差异:GET 请求主要用于请求资源,一般不修改服务器数据;POST 请求可用于请求资源和修改服务器数据,如提交表单、创建新资源等。
  4. 安全性:GET 请求参数暴露在 URL 中,安全性较低;POST 请求相对较高,但仍需注意防范 CSRF 等攻击。

三、Node.js 相关

(一)安装与检测

可从https://nodejs.org/en下载安装 Node.js。安装完成后,在命令提示符中输入node -v,若出现版本信息,则表示安装成功。Node.js 是基于 Chrome V8 引擎的 JavaScript 运行时,它使得 JavaScript 可以在服务器端运行,为前端后端交互提供了强大的支持。

(二)http 模块使用

  1. 创建 HTTP 服务器,并传入处理请求的回调函数。在回调函数中,我们可以获取请求参数和请求体,从而对请求进行处理。
  2. 在回调函数中获取请求参数和请求体。通过req对象,我们可以获取请求的各种信息,如请求方法、请求头、请求体等。
  3. 设置响应头。使用res.setHeader方法设置响应头,例如设置Content-Type 、Content-Length等。
  4. 响应数据。使用res.end方法将响应数据发送给客户端。
  5. 启动服务器并监听指定端口。通过server.listen方法启动服务器,并指定监听的端口号。
const http = require('http');

const server = http.createServer((req, res) => {

    let body = '';

    req.on('data', chunk => {

        body += chunk.toString();

    });

    req.on('end', () => {

        // 处理请求参数和请求体

        res.setHeader('Content-Type', 'text/plain');

        res.end('Hello, World!');

    });

});

server.listen(3000, () => {

    console.log('Server running at port 3000');

});

四、Express 框架使用

Express 是基于 Node.js 的 Web 开发框架,可快速搭建服务器。

(一)安装与初始化

在终端执行npm init --yes初始化项目,然后npm i express安装 Express,也可以使用npm list express查看安装版本。初始化项目会生成package.json文件,用于管理项目的依赖和配置。

(二)使用步骤

  1. 安装 Express 模块:npm install express --save 。--save选项会将 Express 添加到项目的依赖列表中。
  2. 导入 Express 模块:const express = require('express'); 。通过require方法导入 Express 模块,以便在项目中使用。
  3. 创建 HTTP 服务器:const app = express(); 。app对象是 Express 应用的核心,用于定义路由、中间件等。
  4. 设置路由:根据请求的 URL 执行相应的处理函数。路由是 Express 应用的重要组成部分,它决定了如何处理不同的请求。
app.get('/', (Request, Response) => {

    Response.send('hello world');

});

app.post('/post - route', (Request, Response) => {

    let data = Request.body;

    Response.send('Received post data:'+ JSON.stringify(data));

});
  1. 启动服务器并监听端口:
app.listen(8000, () => {

    console.log('服务器启动成功');

});

启动 Express 服务器时,在终端输入node 文件名,如node express基本使用.js。在浏览器地址栏输入http://127.0.0.1:8000/可查看响应结果。若要释放端口,按ctrl + C 。

五、Nodemon 工具

Nodemon 可帮助自动重启 Express 后台服务器。在终端执行npm install -g nodemon进行安装。安装完成后,使用nodemon 文件名启动服务器,如nodemon severs.js。当文件发生变化时,Nodemon 会自动检测并重启服务器,提高开发效率。

六、AJAX 技术

AJAX(Asynchronous JavaScript and XML)用于在不重新加载整个页面的情况下与服务器进行数据交互。

(一)使用 XMLHttpRequest 对象发送请求步骤

  1. 创建 XMLHttpRequest 对象:const xhr = new XMLHttpRequest(); 。XMLHttpRequest对象是 AJAX 的核心,用于发送 HTTP 请求和接收响应。
  2. 设置请求方式和请求地址:xhr.open('GET', 'http://www.example.com/api'); 。通过open方法设置请求的方法(GET、POST 等)和 URL。
  3. 设置请求头(可选):xhr.setRequestHeader('Content-Type', 'application/json'); 。根据需要设置请求头,如Content-Type 、Authorization等。
  4. 发送请求:xhr.send(); 。使用send方法发送请求,若为 POST 请求,可在send方法中传入请求体数据。
  5. 监听onreadystatechange事件,根据请求状态处理响应。readyState属性有 5 种值,0 表示未初始化,1 表示启动,2 表示发送,3 表示接收,4 表示完成。
xhr.onreadystatechange = function () {

    if (xhr.readyState === 4) {

        if (xhr.status === 200) {

            console.log(xhr.responseText);

        } else {

            console.log('请求失败');

        }

    }

};
  1. 获取响应数据,可通过xhr.response(响应体)、xhr.responseText(响应文本数据)、xhr.responseXML(响应 XML 数据)、xhr.status(响应状态码)、xhr.statusText(响应状态字符串)、xhr.getAllResponseHeaders()(所有响应头)获取。

(二)JSONP 解决跨域(仅适用于 GET 请求)

JSONP 利用<script>标签的跨域能力发送请求。

<script src="http://127.0.0.1:8000/jsonp-server"></script>

app.all("/jsonp-server", (request, response) => {

    const data = {

        name: "bdqn"

    };

    let str = JSON.stringify(data);

    response.end(`handle(${str})`);

});

(三)CORS 解决跨域

通过设置响应头允许跨域请求。

response.setHeader("Access-Control-Allow-Origin", "*");

response.setHeader("Access-Control-Allow-Headers", "*");

response.setHeader("Access-Control-Allow-Method", "*");

七、Axios 使用

Axios 是对原生 XMLHttpRequest 的封装,基于 Promise,可用于浏览器和 Node.js 的 HTTP 客户端。

(一)特点

能在浏览器和 Node.js 中发起请求、支持 Promise API、可拦截请求和响应、转换数据、取消请求以及自动转换 JSON 数据。这些特点使得 Axios 在前端开发中非常受欢迎。

(二)安装

通过 CDN 引入:<script src="https://unpkg.com/axios/dist/axios.min.js"></script> 。也可以使用npm install axios进行安装。

(三)基本使用

  1. 准备服务器:使用 json - server 模拟服务器。安装 json - server:npm install -g json-server ;创建数据源(如db.json);启动服务器,可使用json-server db.json 、json-server --watch db.json 或在package.json中配置别名后用npm run mock启动。
  2. 各种请求方式
// GET请求

axios.get('/axios-server', {

    headers: {

        id: "001"

    }

}).then(response => {

    console.log(response.data);

}, error => {

    console.log(error.message);

});

// POST请求

axios.post('/axios - server', {

    username: "admin",

    password: "12345"

}).then(response => {

    console.log(response.data);

}, error => {

    console.log(error.message);

});

// PUT请求

axios.put('/axios - server/1', {

    name: "newName"

}).then(response => {

    console.log(response.data);

}, error => {

    console.log(error.message);

});

// PATCH请求

axios.patch('/axios - server/1', {

    name: "updatedName"

}).then(response => {

    console.log(response.data);

}, error => {

    console.log(error.message);

});

// DELETE请求

axios.delete('/axios - server/1').then(response => {

    console.log(response.data);

}, error => {

    console.log(error.message);

});
  1. 配置:配置优先级为请求配置 > 实例配置 > 全局配置。
// 全局配置

axios.defaults.timeout = 2000;

axios.defaults.baseURL = "http://localhost:3000";

// 实例配置

const instance = axios.create({

    baseURL: "http://localhost:3000",

    timeout: 2000

});

// 请求配置

axios.get("http://localhost:3000/list", {

    timeout: 2000

});
  1. 拦截器:分为请求拦截器和响应拦截器。
// 请求拦截器

axios.interceptors.request.use(config => {

    console.log("开启加载动画");

    console.log("认证是否有token,如果没有,要去登录");

    return config;

}, error => {

    return Promise.reject(error);

});

// 响应拦截器

axios.interceptors.response.use(config => {

    console.log("关闭加载动画");

    console.log("对数据进行一些处理");

    return config.data;

}, error => {

    return Promise.reject(error);

});

(四)Vue 中使用 Axios

  1. 基本使用:通过npm install axios安装;在main.js文件中挂载到 Vue 原型:

import axios from 'axios';

Vue.prototype.$axios = axios;

在组件中使用:

<button @click="getDate">点击发送请求</button>

<script>

export default {

    name: 'App',

    methods: {

        async getDate() {

            let res = await this.$axios.get('http://localhost:3000/list');

            console.log(res.data);

        }

    }

}

</script>
  1. 一次封装:在src/utils目录下创建request.js文件进行封装。
import axios from "axios";

const request = axios.create({

    baseURL: "http://localhost:3000",

    timeout: 2000

});

request.interceptors.request.use(config => {

    config.data = JSON.stringify(config.data);

    config.headers = {

        "Content-Type": "application/x-www-form-urlencoded"

    };

    const token = getCookie("名称");

    if (token) {

        config.params = { token: token };

        config.headers.token = token;

    }

    return config;

}, error => {

    return Promise.reject(error);

});

request.interceptors.response.use(response => {

    console.log('关闭请求数据动画');

    console.log('对数据进行处理');

    return response.data;

}, error => {

    return Promise.reject(error);

});

export default request;

在组件中引入使用:

<script>

import request from '../utils/request';

export default {

    name: 'ShowList',

    methods: {

        async getList() {

            let res = await request.get('/list');

            console.log(res);

        }

    }

}

</script>
  1. 二次封装:在apis目录下创建相关 js 文件,定义具体请求函数。
// src/apis/showList.js

import request from "@/utils/request";

export function getListInfo1() {

    return request.get("/list");

}

export function getUserInfo1() {

    return request.get("/user");

}

在组件中导入使用:

<script>

import { getListInfo1, getUserInfo1 } from '../apis/showList';

export default {

    name: 'ShowList',

    methods: {

        async getList1() {

            let res = await getListInfo1();

            console.log(res);

        },

        async getUser1() {

            let res = await getUserInfo1();

            console.log(res);

        }

    }

}

</script>

八、其他要点

(一)URL 编码

URL 编码用于将非 ASCII 字符转换为 ASCII 字符,非 ASCII 字符会被编码为%xx形式的十六进制字符,如 “你” 编码为%E4%BD%A0。这是为了确保 URL 能够正确传输和解析。

(二)跨域概念

同源要求协议、域名、端口号完全相同,违背同源策略即跨域。跨域会导致前端请求被浏览器拦截,需要通过一些技术手段(如 JSONP、CORS 等)来解决。

通过以上对 HTTP 协议、前端后端交互技术的详细介绍,有助于开发者深入理解并运用这些技术进行 Web 应用开发。在实际开发中,还