首页 > 其他分享 >Web-请求数据+号丢失问题

Web-请求数据+号丢失问题

时间:2024-05-27 13:00:39浏览次数:24  
标签:Web sendData const 请求 编码 URL 丢失 data log

1.背景

先来复习下URL请求的基本知识

HTTP的早期设计主要考虑了基本的文档检索需求以及表单提交功能,这直接影响了后来对POST请求和内容类型的发展。

1.1 请求方法

HTTP(超文本传输协议)最初设计的目的是为了支持万维网上的文档检索,这涉及到请求HTML页面、图像、视频等静态资源。

  • GET

    设计用于请求数据,它将请求信息编码在URL中,适用于检索操作。由于URL长度有限制,并且数据公开可见,这种方法适合非敏感数据的简单检索。

  • POST

    • 随着Web的发展,需要一种方式能在保护用户隐私的前提下发送大量数据。POST应运而生,用于发送数据到服务器以创建或更新资源。
    • 最初,POST主要用来提交表单数据,这些数据不适合通过URL传输(例如,由于安全、大小或隐私考虑)。

1.2 请求内容类型

随着Internet的应用日益广泛,对表单处理能力的需求增加,引入了几种内容类型来支持更复杂的交互:

  • application/x-www-form-urlencoded

    • 这是最早用于支持HTML表单数据提交的内容类型。由于HTML表单是早期Web交互的核心,因此这种内容类型设计来处理简单的文本数据。
    • 它简单地将表单数据编码为名/值对,与URL查询字符串使用相同的格式,不过是放在了请求体中。
  • multipart/form-data

    • 随着文件上传需求的出现,application/x-www-form-urlencoded方式由于其编码方式(特别是空间效率问题)并不适合处理文件或大量数据。
    • 因此,multipart/form-data被引入,支持表单中的文件上传以及包含二进制数据的需求。
  • application/json

    • 随着Web服务和API的普及,尤其是RESTful架构的推广,需要一种更灵活、能支持复杂数据结构(如对象和数组)的数据交换格式。
    • JSON因其易于人类读写和机器解析生成的特性,成为数据交互的首选格式,尤其在Web应用与服务器之间。

2.URL保留字符

在URL中,某些字符有特殊的意义,被称为“保留字符”。这些字符通常用于分隔URL的不同部分,如路径、查询参数和片段标识符。

字符 用途 URL编码
: 分隔协议和地址、端口号 %3A
/ 分隔URL路径的各个部分 %2F
? 标记URL的查询部分的开始 %3F
# 标记URL的片段标识符的开始 %23
[ 在URL中用于特定的语法结构 %5B
] 在URL中用于特定的语法结构 %5D
@ 在URL中指定用户名和密码 %40
! 子分隔符,有时用于注入特殊意义 %21
$ 子分隔符,用于处理特定数据 %24
& 分隔URL中的查询参数 %26
' 子分隔符,用于封装数据 %27
( 子分隔符,用于更复杂的数据结构 %28
) 子分隔符,用于更复杂的数据结构 %29
* 子分隔符,有时用于URL中的通配符 %2A
+ 子分隔符,用于空格的替代符,尤其是在表单数据中 %2B
, 子分隔符,用于分隔数据 %2C
; 分隔URL参数 %3B
= 分隔URL中的参数名称和值 %3D

好,现在问题就来了,在不进行URL编码的时候,+号默认译为空格。

3.问题场景

根据上面的分析,我们可以看到,常见的问题点在2个场景。

3.1 URL路径

跟方法get/post无关,关键是路径中直接使用+号,会被默认解释为空格。

@Slf4j
@RestController
@RequestMapping("/index")
public class IndexController {

    @RequestMapping("/a")
    public String index1(@RequestParam String data) {
        log.info("data: {}", data);
        return "{\"ret\":\"ok\"}";
    }
}

image-20240527123257744

image-20240527123312969

3.2 内容类型

application/x-www-form-urlencoded使用的也是简单的字符串拼接方式,问题主要发生在这里

其余两个类型内容转换的方法不一样,不会有这个问题。

<script setup></script>

<template>
  <div id="app">
    <form @submit.prevent="handleSubmit">
      <input v-model="inputData" type="text" placeholder="++++++++++++++++" />
      <button type="submit">Submit</button>
    </form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      inputData: ''
    }
  },
  methods: {
    handleSubmit() {
      console.log('Before encoding: ', this.inputData)
      const sourceData = this.inputData
      const encodedData = encodeURIComponent(this.inputData)

      // 源字符串
      console.log('Source data: ', sourceData)
      // URL编码
      console.log('URL Encoded data: ', encodedData)

      // 直接发送的是源字符串
      this.sendData(sourceData)
    },

    sendData(sendData) {
      fetch('http://127.0.0.1:8090/index/b', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: `data=${sendData}`
      })
        .then((response) => response.json())
        .then((data) => console.log('Server response: ', data))
        .catch((error) => console.error('Error:', error))
    }
  }
}
</script>

package cn.yang37.za.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

/**
 * @description:
 * @class: IndexController
 * @author: [email protected]
 * @date: 2024/5/27 11:40
 * @version: 1.0
 */
@Slf4j
@RestController
@RequestMapping("/index")
public class IndexController {
    @RequestMapping("/b")
    @CrossOrigin(origins = "http://localhost:5173")
    public String index2(@RequestParam String data) {
        log.info("data: {}", data);
        return "{\"ret\":\"ok\"}";
    }
}

这里,我们直接使用未编码的sourceData进行发送,即this.sendData(sourceData)

image-20240527123529125

image-20240527123607585

4.解决方案

上面可以看到,问题的根源都在于没有进行URL编码。

4.1 URL路径

// 源参数
const userInput = "这 是 一 堆 特 殊 字 符 / = &";

// url编码
const encodedInput = encodeURIComponent(userInput);

// 路径里使用编码后的
const url = `https://example.com/data/${encodedInput}`;

同理啊,有没有想过,平时看到的是?key=value&key2=value2的格式。

那假设发送的key或者value有特殊符号呢,例如key是name?n&666,value是value&123

https://example.com/api?name?n&666=value&123

你看,你自己都分不清,换成这样你才理解。

https://example.com/api?name%3Fn%26666=value%26123
const baseUrl = "https://example.com/api";
const key = "name?n&666";
const value = "value&123";

const encodedKey = encodeURIComponent(key);
const encodedValue = encodeURIComponent(value);

const url = `${baseUrl}?${encodedKey}=${encodedValue}`;
console.log(url);

当然一般不会这样,但又不是不允许。

所以,碰到特殊符号,记得想起来先编码。

4.2 内容类型

思路一致,application/x-www-form-urlencoded把要发送的内容,进行URL编码。

  methods: {
    handleSubmit() {
      console.log('Before encoding: ', this.inputData)
      const sourceData = this.inputData
      const encodedData = encodeURIComponent(this.inputData)

      // URL编码
      console.log('URL Encoded data: ', encodedData)
      // 用编码后的数据
      this.sendData(encodedData)
    },

    sendData(sendData) {
      fetch('http://127.0.0.1:8090/index/b', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: `data=${sendData}`
      })
     
    // ...

标签:Web,sendData,const,请求,编码,URL,丢失,data,log
From: https://www.cnblogs.com/yang37/p/18215272

相关文章

  • 1915springboot VUE 宠物寄养平台系统开发mysql数据库web结构java编程计算机网页源码m
    一、源码特点 springbootVUE宠物寄养平台系统是一套完善的完整信息管理类型系统,结合springboot框架和VUE完成本系统,对理解JSPjava编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统具有完整的源代码和数据库,系统主要采用B/S模式开发。springbootVUE宠物寄养......
  • vpnike.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个vpnike.dll文件(挑选合适的版本文件)把它放......
  • w32time.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个w32time.dll文件(挑选合适的版本文件)把它放......
  • uxsms.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个uxsms.dll文件(挑选合适的版本文件)把它放入......
  • usbmon.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个usbmon.dll文件(挑选合适的版本文件)把它放......
  • 【JAVA】Java如何使用Spring Boot进行Web服务开发
    文章目录前言一、函数解释二、代码实现三、总结前言在现代的微服务架构中,创建快速、可靠的Web服务已经成为一项基本技能。SpringBoot是一个出色的框架,它简化了Spring应用开发,使我们能够更快速地创建和部署Web服务。在这篇博客中,我们将探讨如何使用Java和SpringBoo......
  • EAS_WEB获取传参,获取上下文,获取控制单元
    varimp=JavaImporter();imp.importPackage(Packages.java.lang);imp.importPackage(Packages.org.apache.commons.lang3);imp.importPackage(Packages.com.kingdee.bos.webframework.context);imp.importPackage(Packages.com.kingdee.eas.util.app);imp.importPackage(......
  • 在Linux中,如何配置Web服务器(如Apache或Nginx)?
    在Linux系统中配置Web服务器是建立网站托管环境的关键步骤之一。下面将详细介绍如何在Linux中配置两种流行的Web服务器:Apache和Nginx:一、ApacheWeb服务器的配置:安装Apache服务器:首先确认Apache是否已安装在系统上。这可以通过运行rpm-qa|grep-ihttpd(针对RedHat系列)或......
  • 请求走私详解
    请求走私漏洞前言前两天外出去打了数字中国数据安全赛道的线下赛,题目挺有意思的,学到不少新东西。请求走私漏洞便是其中之一。这个点应该是决赛上午共同防御的的一道题目,整体的思路听上去分享情报的师傅说是先用工具打shiro框架,生成payload后用请求走私绕过后台WAF的长度限制。当......
  • Web系列-前端游戏
    Web系列-前端游戏在CTF比赛web题目中,出题人为了添加趣味性,常有将web小游戏作为题目的,本篇博客会将自己遇到的web前端游戏题目记录在这里。[NewStarCTF2023公开赛道]游戏高手是一个飞机大战的游戏题目说100000分就给flag,F12看看游戏游戏代码在app_v2.js中找到关键代码//......