关于querystring问题。(标签-json|关键词-post)(语言-javascript)

现在有个post请求,request head 只能是application/x-w-urlend,参数是data={ page:1,rows:10,jsonnal:{a:1,b:2,st:'2023-03-12 10:00:00',et:'2023-03-13 14:00:00'},正常来说我先Json.stringify这个jsonnal,然后superagent.send(querystring(data)),现在问题是如果jsonal里是日期,也就是2023-03-12,的话能请求到结果,如果像现在这样,是具体日期时间,就报错。看了下可能是空格的原因,看了下网页上请求的时候,urlsource把空格变成了+号,但是querystring后空格是%20。请各位帮忙解决下,结果要打印下querystring(data),我看看和网页上的对不对!不能更改请求头!

在构造POST请求的时候,如果要发送JSON格式的数据,建议使用Content-Type为application/json的方式发送请求,而不是使用application/x-www-form-urlencoded格式。如果只能使用application/x-www-form-urlencoded格式发送请求,建议将JSON对象序列化为字符串,并使用encodeURIComponent()方法对参数字符串进行URL编码,以便发送特殊字符。

在您的情况下,您可以尝试使用encodeURIComponent()方法来对JSON对象中的日期字符串进行编码,然后将编码后的字符串作为请求参数发送。您可以使用以下代码示例来构造请求:

const superagent = require('superagent');
const querystring = require('querystring');

const data = {
  page: 1,
  rows: 10,
  jsonnal: {
    a: 1,
    b: 2,
    st: '2023-03-12 10:00:00',
    et: '2023-03-13 14:00:00'
  }
};

// 对jsonnal对象中的日期字符串进行编码
data.jsonnal.st = encodeURIComponent(data.jsonnal.st);
data.jsonnal.et = encodeURIComponent(data.jsonnal.et);

// 使用querystring.stringify()方法将JSON对象序列化为URL编码的字符串
const postData = querystring.stringify({ data: JSON.stringify(data) });

// 发送POST请求
superagent
  .post('/api/your-api-url')
  .set('Content-Type', 'application/x-www-form-urlencoded')
  .send(postData)
  .then((response) => {
    console.log(response.body);
  })
  .catch((error) => {
    console.log(error);
  });

// 打印请求参数
console.log(querystring.stringify({ data: JSON.stringify(data) }));

在这个示例代码中,对jsonnal对象中的日期字符串进行了编码,并使用querystring.stringify()方法将JSON对象序列化为URL编码的字符串。然后,我们使用superagent库发送POST请求,并在控制台打印响应结果和请求参数。请注意,在控制台打印请求参数时,空格会被URL编码为%20。

该回答引用ChatGPT

如有疑问,可以回复我!

你可以使用encodeURIComponent() 函数来将空格转换为 %20,它是将 URI 组件进行编码的 JavaScript 函数。所以,你可以将数据中的日期字符串先使用 encodeURIComponent() 进行编码,然后再将整个数据对象转换为 URL 查询参数字符串,如下所示:


const querystring = require('querystring');
const superagent = require('superagent');

const data = {
  page: 1,
  rows: 10,
  jsonnal: {
    a: 1,
    b: 2,
    st: '2023-03-12 10:00:00',
    et: '2023-03-13 14:00:00'
  }
};

// 编码日期字符串
data.jsonnal.st = encodeURIComponent(data.jsonnal.st);
data.jsonnal.et = encodeURIComponent(data.jsonnal.et);

const queryString = querystring.stringify(data);
console.log(queryString); // 输出查询参数字符串

superagent
  .post(url)
  .set('Content-Type', 'application/x-www-form-urlencoded')
  .send(queryString)
  .then(response => {
    console.log(response.body);
  })
  .catch(error => {
    console.error(error);
  });

这样做应该就能够正确地将空格转换为 %20,并发送 POST 请求了。

参考GPT和自己的思路:querystring 函数在编码时会将空格编码为 %20,这可能会导致服务器无法正确解析参数。为了解决这个问题,你可以使用 JavaScript 的 encodeURIComponent 函数来手动编码参数,这样空格就会被编码为 +:

const data = {
  page: 1,
  rows: 10,
  jsonnal: {
    a: 1,
    b: 2,
    st: '2023-03-12 10:00:00',
    et: '2023-03-13 14:00:00'
  }
};

const query = querystring.stringify({
  data: JSON.stringify(data)
}).replace(/%20/g, '+');

superagent
  .post('/api')
  .set('Content-Type', 'application/x-www-form-urlencoded')
  .send(query)
  .then(response => {
    console.log(response.body);
  });


在这个例子中,我们首先使用 JSON.stringify 将数据对象转换为字符串,然后使用 querystring.stringify 函数编码成查询字符串。最后,我们使用 replace 函数将所有的 %20 替换为 +。

可以试试使用qs.stringify()方法来将参数序列化为 URL 查询字符串。qs.stringify()方法默认将空格转换为+号,而非%20。 例如,您可以这样修改代码:

const qs = require('qs');
const superagent = require('superagent');

const data = {
  page: 1,
  rows: 10,
  jsonnal: {
    a: 1,
    b: 2,
    st: '2023-03-12 10:00:00',
    et: '2023-03-13 14:00:00'
  }
};

const queryStr = qs.stringify({ data: JSON.stringify(data) });
console.log(queryStr);

superagent
  .post(url)
  .type('form')
  .send(queryStr)
  .end(function(err, res) {
    if (err) {
      console.log('error:', err);
    } else {
      console.log('response:', res);
    }
  });

其中,qs.stringify()data对象序列化为 URL 查询字符串,然后把它作为superagent.send()方法的参数。type('form')的作用是设置请求头的Content-Typeapplication/x-www-form-urlencoded,这是一种常用的 POST 请求的请求头类型。 在控制台中,可以看到queryStr的打印结果,确保其中的空格已经被转换成+号。同时,superagent发送的 POST 请求也应该是正确的了。

该回答引用GPTᴼᴾᴱᴺᴬᴵ
可以使用JavaScript中的encodeURIComponent()方法来对查询字符串中的特殊字符进行编码,包括空格。

你可以将 data 对象中的jsonnal属性序列化为JSON字符串,然后对其进行URL编码。具体代码如下:

const data = {
  page: 1,
  rows: 10,
  jsonnal: {
    a: 1,
    b: 2,
    st: '2023-03-12 10:00:00',
    et: '2023-03-13 14:00:00'
  }
};

const jsonnalString = JSON.stringify(data.jsonnal);
const encodedJsonnalString = encodeURIComponent(jsonnalString);

const querystring = `data=${encodeURIComponent(JSON.stringify({
  ...data,
  jsonnal: encodedJsonnalString
}))}`;

console.log(querystring);


这里先将jsonnal属性的值序列化为JSON字符串,然后将其进行URL编码。接着,使用encodeURIComponent()方法将整个data对象序列化为JSON字符串并进行URL编码。最终的查询字符串会输出到控制台。

可以尝试把空格转换成加号,然后再将数据进行序列化。这样可以确保空格不会引起问题。

以下是一个示例代码,可以参考一下:

const superagent = require('superagent');
const querystring = require('querystring');

const data = {
  page: 1,
  rows: 10,
  jsonnal: {
    a: 1,
    b: 2,
    st: '2023-03-12+10:00:00',
    et: '2023-03-13+14:00:00'
  }
};

// 将空格替换成加号
data.jsonnal.st = data.jsonnal.st.replace(/ /g, '+');
data.jsonnal.et = data.jsonnal.et.replace(/ /g, '+');

const query = querystring.stringify(data);

console.log(query);

superagent
  .post('/api')
  .set('Content-Type', 'application/x-www-form-urlencoded')
  .send(query)
  .end((err, res) => {
    // 处理响应结果
  });


参考GPT和自己的思路,你可以使用Node.js内置的querystring模块中的stringify方法将数据对象转换为URL查询字符串。但是,querystring模块默认将空格编码为%20,而不是+号,因此需要自定义一个函数将空格编码为+号。

以下是一个可以帮助你解决问题的代码示例:

const querystring = require('querystring');
const superagent = require('superagent');

// 自定义函数,将空格编码为+号
function encodeSpace(str) {
  return str.replace(/\s/g, '+');
}

const data = {
  page: 1,
  rows: 10,
  jsonnal: {
    a: 1,
    b: 2,
    st: '2023-03-12 10:00:00',
    et: '2023-03-13 14:00:00'
  }
};

// 将jsonnal对象转换为字符串,并将其中的空格编码为+号
data.jsonnal = encodeSpace(JSON.stringify(data.jsonnal));

const queryString = querystring.stringify(data);

superagent
  .post('/your-api-endpoint')
  .set('Content-Type', 'application/x-www-form-urlencoded')
  .send(queryString)
  .then((res) => {
    console.log(res.body);
  })
  .catch((err) => {
    console.error(err);
  });

console.log(queryString);

注意,由于你的请求头为application/x-www-form-urlencoded,因此需要在发送请求时将Content-Type设置为application/x-www-form-urlencoded。

此外,上面的代码示例还会打印出生成的查询字符串,你可以将其与网页上的查询字符串进行比较,以验证它们是否相同。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在使用 querystring 时,空格应该被编码为 %20,而不是 + 号,因为在发送网络请求时,+ 号是被解码成空格的。因此,你需要将空格替换为 %20,可以使用 JavaScript 内置的 encodeURIComponent() 函数。

另外,由于要发送 JSON 格式的数据,应该将请求头设置为 application/json 而不是 application/x-www-form-urlencoded,可以使用 superagent 库的 set() 方法设置请求头。

以下是一个示例代码:

const superagent = require('superagent')
const querystring = require('querystring')

const data = {
  page: 1,
  rows: 10,
  jsonnal: {
    a: 1,
    b: 2,
    st: '2023-03-12 10:00:00',
    et: '2023-03-13 14:00:00'
  }
}
const jsonString = JSON.stringify(data.jsonnal)
const encodedJsonString = encodeURIComponent(jsonString)

const query = querystring.stringify({
  page: data.page,
  rows: data.rows,
  jsonnal: encodedJsonString
})

superagent
  .post('/api/data')
  .set('Content-Type', 'application/json')
  .send(data)
  .end((err, res) => {
    if (err) {
      console.error(err)
      return
    }
    console.log('response:', res.body)
  })

console.log('querystring:', query)

在这个例子中,我们先将 jsonnal 对象转换为 JSON 字符串,然后对该字符串进行 encodeURIComponent() 编码,生成一个经过编码的字符串。然后将要发送的数据直接通过 send() 方法发送,而不是使用 querystring 模块。

最后,我们使用 console.log() 打印生成的查询字符串,以便与网页上的查询字符串进行对比。
如果我的回答解决了您的问题,请采纳!

要对querystring进行编码,否则会出现错误。