Solicitud Ajax y paquete axios en desarrollo front-end

Tabla de contenido

solicitud http del navegador

Sincronice etiquetas js entre dominios y URL

ajax asíncrono, protocolo websock

Ajax es un término técnico asíncrono y la API más antigua es xhr (XMLHttpRequest)

obtener la API de es6

axios

Paquete axios

src/utils/request.ts

src/utils/func.ts

SSO (Single Sign-On) inicio de sesión único, un inicio de sesión puede acceder a múltiples programas independientes

expresión regular

caracteres comunes

Búsqueda hacia adelante/hacia atrás: coincide con lo que está entre paréntesis (excluyendo paréntesis)

src/api/common.ts

src/vistas/componentes

Revisión de conocimientos básicos

parámetros de URL

valor del atributo de ubicación

Política del mismo origen

cookie de suma de fichas

Reemplazar cookies (simular usuarios con diferentes permisos en desarrollo)

A. Manualmente

B. Establecer index.html 

C. Subprograma de extensión del navegador: obtener/establecer varios con un solo clic

seguridad web

Ataque de secuencias de comandos entre sitios XSS Cross-Site Scripting (ejecutar la lectura de secuencias de comandos al iniciar sesión)

Falsificación de solicitud entre sitios CSRF Falsificación de solicitud entre sitios (solicitud de credencial)

Ataque de inyección SQL (envíe el formulario/ingrese el nombre de dominio para ejecutar el comando SQL)

Ataque DDoS Denegación de servicio distribuida Denegación de servicio distribuida (sobrecarga de solicitud)


solicitud http del navegador

Sincronice etiquetas js entre dominios y URL

<img origen>, <enlace href>

ajax asíncrono, protocolo websock

Ajax es un término técnico asíncrono y la API más antigua es xhr (XMLHttpRequest)

obtener la API de es6

Basado en promesas, fácil de usar 

axios

  • Isomórfico, es decir, el mismo código está disponible en el lado de nodejs y en el lado del navegador
  • Use xhr en el navegador y use el módulo http integrado de Node en Node.js.
// 在浏览器中,根据其Content-Type头信息,自动转换数据
axios.get('/api/data').then(response => {
  // response.data 将是一个JavaScript对象
});

// 在Node.js中手动设置响应数据类型
axios.get('/api/data', { responseType: 'json' }).then(response => {
  // response.data 将是一个JavaScript对象
});
  • La nueva versión de axios también es compatible con fetch
  • Las bibliotecas de terceros se basan en la API nativa, por lo que axios todavía se basa en xhr

[JavaScript] ¡20.000 caracteres! Comprenda la diferencia entre Ajax, Fetch y Axios al mismo tiempo ~ Desarrollar papel

Paquete axios

Interceptor de solicitud/respuesta src/utils/request.ts

import service from 'axios'
import { handleSSO } from '@/utils/func'
import router from '@/router/index'

// 请求拦截器
service.interceptors.request.use(
  (config: any) => {
    // 在请求头中添加XMLHttpRequest字段
    config.headers['X-Requested-With'] = 'XMLHttpRequest'
    return config
  },
  (error: any) => {
    console.log('request:', error) // 用于调试的错误信息
    return Promise.reject(error)
  }
)

function errorMsgTips(msg: any) {
  window.$message.error(msg)
}

// 响应拦截器
service.interceptors.response.use(
  (response: { data: any; config: any }) => {
    const resData = response.data || {}
    if (resData.code === 302) {
      // 如果响应码为302,进行页面重定向到指定链接
      window.location.href = `https://www.example.com/path/to/resource.html/domain=${location.host}&req=${encodeURIComponent(location.pathname)}&protocol=https${location.hash}`
    } else if (resData.code == 0 || resData.code == 200) {
      // 如果响应码为0或200,则直接返回响应数据
      return resData
    } else if (resData.code == 4004) {//自定义响应码
      // 如果响应码为4004,说明没有权限,跳转至无权限页面
      router.push({
        path: '/notPermission'
      })
    } else {
      // 其他情况下,显示错误提示消息
      errorMsgTips(resData.message || '接口错误,请稍后重试')
    }
  },
  (error: any) => {
    if (service.isCancel(error)) {
      console.log('取消请求 error -> ', error)
      return
    }
    if (error && error.response && error.response.status === 302) {
      if (process.env.NODE_ENV === 'development') {
        // 如果是开发环境,并且错误码为302,显示替换SSO_SESSION_ID的提示
        errorMsgTips('请替换Cookies里的SSO_SESSION_ID')
        return
      } else {
        // 非开发环境下,进行单点登录重定向
        window.location.href = handleSSO('login')
      }
    } else if (error && error.stack.includes('timeout')) {
      // 如果错误信息中包含"timeout",显示接口超时错误提示
      errorMsgTips('接口超时')
      return
    } else if (error && error.stack.includes('Network')) {
      // 如果错误信息中包含"Network",显示网络异常错误提示
      errorMsgTips('网络异常')
      return
    }
    return Promise.reject(error)
  }
)

export default service

Herramientas src/utils/func.ts

/**
 * 清除会话
 * @param
 */
function clearSession() {
  //匹配不包含空格和分号的字符,该字符后面必须跟着一个等号。这会返回一个由cookie键组成的数组。
  const keys = document.cookie.match(/[^ =;]+(?=\=)/g)
  if (keys) {
    for (let i = keys.length; i--; )
     //) 创建了一个代表时间戳 0 的 JavaScript Date 对象,并将其转换为 UTC 字符串。
     //这个时间对应于 1970 年 1 月 1 日 协调世界时 (UTC) 时间 00:00:00。
      document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
  }
  sessionStorage.clear()
  localStorage.clear()
}

/**
 * SSO登入登出
 * @param SSOtype
 * login登入
 * logout登出
 */
export function handleSSO(SSOtype: string): string {
  const hostStr = 'passport.example.com'
  clearSession()
  return `https://${hostStr}/${SSOtype}?service=` + encodeURIComponent(window.location.origin)
}

SSO (Single Sign-On) inicio de sesión único, un inicio de sesión puede acceder a múltiples programas independientes

Generalmente implementado por token/cookie

expresión regular

caracteres comunes

· Coincide con cualquier carácter individual excepto un carácter de nueva línea
* Coincide con el carácter anterior cero o más veces. Por ejemplo, "zo*" coincide con "z" o "zoo".
+ coincide con el carácter anterior una o más veces. Por ejemplo, "zo+" coincide con "zoo", pero no con "z".
? coincide con el carácter anterior cero o una vez. Por ejemplo, "a?ve?" coincide con "ve" en "nunca".
x|y coincide con x o y
{n} coincide n veces. n es un número entero no negativo
{n,} n es un número entero no negativo . Al menos Coincide n veces. Por ejemplo, "o{2,)" no coincide con la "o" de "Bob", pero coincide con todas las o de "comidaooood". "o{1}" es equivalente a "o+" ." o{0,}" y "o*" son equivalentes.
{n,m}m y n son números enteros no negativos. Coinciden al menos n y como máximo m veces. Por ejemplo, "o{1,3] " y "fooooood" Coincide con las tres primeras o en "o{0,1}" y "o?" son equivalentes.
[xyz] coincide con cualquier carácter dentro de los corchetes. Por ejemplo, "[abc]" y "a en " simple" "partido.

[^xyz] coincide con cualquier carácter que no esté entre corchetes. Por ejemplo, "[^abc]" coincide con la "p" en "normal".
[az] rango de caracteres. Coincide con cualquier carácter en el rango especificado. Por ejemplo, "[az]" coincide con cualquier carácter alfabético en minúsculas en el rango de "a" a "z".

[^mz] niega un rango de caracteres. Coincide con cualquier carácter que no esté en el rango especificado. Por ejemplo, "[mz]" coincide con cualquier carácter que no esté en el rango de "m" a "z".

Búsqueda hacia adelante/hacia atrás: coincide con lo que está entre paréntesis (excluyendo paréntesis)

Búsqueda hacia atrás : (?<=exp) es una cadena que comienza con exp , pero no se contiene a sí misma .

Búsqueda directa : (?=exp) coincide con la cadena que termina en exp , pero no se contiene a sí misma .

Lookbehind negativo : (?<!exp)  , la subexpresión especificada antes no puede coincidir .

Búsqueda anticipada negativa :: (la subexpresión especificada después no se puede comparar .

La aserción anticipada positiva  significa  que la aserción se realiza en la posición anterior  (?=\=) al signo igual correspondiente  , es decir, la posición anterior debe ir seguida del signo igual  para coincidir. Tales afirmaciones no consumen caracteres reales.==

Lookahead  (?==) significa hacer coincidir el signo igual  == incluir el signo igual en el resultado de la coincidencia. Esta búsqueda consume el signo igual del carácter  = .

Solicitud de paquete src/api/common.ts

import request from '@/utils/request'
const baseUrl = process.env.NODE_ENV === 'development' ? '/test' : ''
const mock = false

// 查看自己信息接口
export const commonQuery = (data: any) => {
  const url = mock ? `${baseUrl}/common/query` : `${baseUrl}/mock/query`
  return request.post(url, data)
}

// 查看自己信息接口
export const getUserInfo = () => {
  const url = `${baseUrl}/menu/userInfo`
  return request.get(url)
}

src/vistas/solicitudes de componentes

import * as API from "@/api/common"
...
 API.commonQuery(params).then((res: any) => {
      console.log('res::::', res)
    })

Revisión de conocimientos básicos

parámetros de URL

http://example.com/page?param1=value1¶m2=value2#section1

? Separe la URL real y los parámetros
& Separador entre parámetros especificados en la URL
= El lado izquierdo es el nombre del parámetro, el lado derecho es el valor del parámetro
#

Anchor (Ancla), utilizado para identificar una ubicación o elemento específico en el documento,

Usado solo en el lado del cliente y procesado por el navegador, no enviado al servidor

Indica al navegador que se desplace hasta id="section1"el elemento con la extensión .

valor del atributo de ubicación

El objeto global de la ventana, que representa la página actual http://www.example.com/path/index.html

ventana.ubicación.href: obtener/establecer URL

window.location.orgin: secciones de protocolo, nombre de host y número de puerto

//https://www.example.com:8080/page.html
//     ://               :
//https%3A%2F%2Fwww.example.com%3A8080。
encodeURIComponent(window.location.origin)
//encodeURIComponent用于将字符串中的特殊字符(空格、&、+、= 、?)转换为编码形式,确保URL中不包含任何无效字符



//查询参数时 或者 动态参数时 需要encodeURIComponent
const url = 'https://example.com/api?param=' + encodeURIComponent(queryParam);
window.location.href =`https://www.example.com/path/to/resource.html/domain=${location.host}&req=${encodeURIComponent(location.pathname)}&protocol=https${location.hash}`

ventana.ubicación.protocolo: protocolo http

ventana.ubicación.host: host + puerto (host:8080)/dirección IP (127.123.32.1 única)/nombre de dominio (www.example.com mnemotécnico)

ventana.ubicación.nombre de host: host host

ventana.ubicación.puerto: puerto 8080

window.location.pathname: ruta del recurso ruta/index.html, recurso index.html

ventana.ubicación.hash:

ventana.ubicación.búsqueda: buscar

var searchParams = new URLSearchParams(window.location.search);
console.log(searchParams.get('name')); // 输出 "John"

Política del mismo origen

Mismo origen/dominio: como sugiere el nombre, el nombre de dominio debe ser el mismo, incluido el prefijo y, por supuesto, el número de puerto.

Pero la cookie puede ser diferente a partir del número de puerto

Las solicitudes de origen cruzado no llevan cookies de forma predeterminada.

Sin embargo, las solicitudes de origen cruzado con cookies se pueden permitir configurando el encabezado CORS (intercambio de recursos de origen cruzado).

withCredentialsEl atributo es truedecirle al navegador que lleve la cookie en la solicitud.

cookie de suma de fichas

certificado simbólico Galleta
dominio cruzado

La aplicación administra completamente el token, por lo que puede evitar la política del mismo origen

Gestión de generación del lado del servidor, no entre dominios
con sesión

El terminal móvil no admite muy bien las cookies, por lo que el token se usa comúnmente en el terminal móvil

la sesión debe implementarse en función de la cookie

Reemplazar cookies (simular usuarios con diferentes permisos en desarrollo)

A. Manualmente

B. Establecer index.html 

<!DOCTYPE html>
<html lang="">
  <head>
...
    <div id="app"></div>
    <script>
      document.cookie = 'sso_ticket=xx'
    </script>
  </body>
</html>

C. Subprograma de extensión del navegador: obtener/establecer varios con un solo clic

Obtenga las cookies en la página web del proyecto y luego configúrelas en la página web del proyecto local


seguridad web


Ataque de secuencias de comandos entre sitios XSS Cross-Site Scripting (ejecutar la lectura de secuencias de comandos al iniciar sesión)

resolver:

  • El parámetro url se escapa usando el método encodeURIComponent
  • Intenta no insertar contenido HTML con InnerHtml

Falsificación de solicitud entre sitios CSRF Falsificación de solicitud entre sitios (solicitud de credencial)

Solución: agregar código de verificación , usar token

Ataque de inyección SQL (envíe el formulario/ingrese el nombre de dominio para ejecutar el comando SQL)

Solución: Convertir algunos caracteres especiales a través de expresiones regulares al ingresar al formulario

Ataque DDoS Denegación de servicio distribuida Denegación de servicio distribuida (sobrecarga de solicitud)

resolver:

  • Limite la frecuencia de las solicitudes de una sola IP.
  • Verifique las aperturas de puertos privilegiados

Supongo que te gusta

Origin blog.csdn.net/qq_28838891/article/details/131445311
Recomendado
Clasificación