GET 请求通过 Postman 工作,但浏览器告诉我 GET 请求不能有正文

Posted

技术标签:

【中文标题】GET 请求通过 Postman 工作,但浏览器告诉我 GET 请求不能有正文【英文标题】:GET request working through Postman but the browser tells me GET request cannot have body 【发布时间】:2020-07-29 09:53:47 【问题描述】:

我只是尝试使用fetch 通过 GET 请求发送一些 urlencoded 参数。我现在只是尝试使用 Express 打印参数,如下所示:

app.get('/api', function (req, res) 
    console.log(req.body);
    res.sendStatus(200);
    return;
);

这在 Postman 中使用 GET 请求和 x-www-form-urlencoded 键值对可以正常工作。网络服务器将打印所有的键值对就好了。

但是当我尝试使用fetch 来做同样的事情时,除了问题我什么也得不到。我尝试了两种不同的方法:

fetch(`http://localhost:3000/api?user=test&password=123`, 
    headers: 
    'Content-Type': 'application/x-www-form-urlencoded'
    
);

请求确实使用此方法通过,但网络服务器仅打印 - 一个空对象。

var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");

var urlencoded = new URLSearchParams();
urlencoded.append("user", "test");
urlencoded.append("password", "123");

var requestOptions = 
    method: 'GET',
    headers: myHeaders,
    body: urlencoded,
;

fetch("localhost:3000/api", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

请求没有使用这种方法通过,浏览器给我错误TypeError: Window.fetch: HEAD or GET Request cannot have a body. 此代码是使用在 Postman 中使用生成代码 sn-ps 选项的有效请求生成的。

我做错了什么?

【问题讨论】:

【参考方案1】:

此网址中的参数:

http://localhost:3000/api?user=test&password=123

在查询字符串中,而不是在正文中,因此content-type 不适用于它们 - 它们被正确编码为在 URL 中。在 Express 中,您可以使用 req.query 访问这些内容。您应该会在您的 Exprss 请求处理程序中看到 req.query.userreq.query.password 的值。

请注意,不建议您在这样的 URL 中发送用户凭据,因为 URL 通常存在于您的 ISP、接收服务器、代理、浏览器历史记录等的日志文件中...用户凭据像这样应该通过 https 在 POST 请求中发送,凭据将在正文中编码(不会被中间人记录或保存)。

提取错误是准确的。 GET 请求没有随它们一起发送的正文。这将用于 POST 或 PUT 请求。 GET 请求是对您仅使用 URL 指定的资源的“获取”请求。

【讨论】:

这是有道理的,我得到了它的工作,非常感谢。邮递员只是忽略了这个错误并发送了一个尸体吗?这完全让我搞砸了。我只是以用户名和密码为例,我实际上是在发送不同的数据,但这可能是一个不好的例子,因为正如你所说,凭据应该放在 POST 请求中。 @Grav - 我们必须查看实际请求的网络跟踪才能了解 Postman 在做什么,但无论如何,这不是您使用 GET 请求的方式。【参考方案2】:

您将请求正文与查询字符串混淆了。

您的第二个请求(您不需要 Content-Type)

fetch("http://localhost:3000/api?user=test&password=123");

将由以下 Express 函数处理:

app.get('/api', function (req, res) 
    console.log(req.query); // Note that query, not body is used.
    res.sendStatus(200);
    return;
);

您可以通过req.query.user && req.query.password 访问查询对象中的字段。

至于GET请求中有请求体:虽然RFC没有明确禁止它,但它要求服务器不要根据请求体的内容改变响应,即GET中的请求体有标准中没有任何意义,所以 JS HTTP APIs (fetch & XmlHttpRequest) 否认它。

【讨论】:

【参考方案3】:

首先,如果您尝试从您的 API 或其他 API 获取一些数据,您应该执行 GET 请求以便从服务器获取您想要的数据,例如,如果您想获取特定的东西,例如用户或其他东西可以使用查询字符串或路由参数在 GET 请求 URL 中传递您的数据。 其次,如果您想验证身份并将您的凭据发送到服务器,则不建议使用 GET 请求,因为我之前说过 GET 请求只是用于从服务器获取一些数据,所以如果您想发送您的凭据或其他任何东西,您会更好关闭使用 POST 请求将数据发送到服务器,并且您不能在浏览器中执行 POST 请求,因此您必须使用 postman 或 insomnia 之类的东西才能将您的 POST 请求发送到服务器。我希望它可以帮助您解决您的问题。

【讨论】:

以上是关于GET 请求通过 Postman 工作,但浏览器告诉我 GET 请求不能有正文的主要内容,如果未能解决你的问题,请参考以下文章

GET 请求在浏览器中有效,但在 POSTMAN 或 SOAPUI 中无效

POSTMAN的get请求不支持设置header

GET 请求在浏览器中有效,但在使用 Postman 时我得到了未经授权

CORS 正在阻止 PUT、DELETE 和 POST 请求,但 GET 正在工作

GET 请求预检在浏览器中失败(使用 React 框架)

GET 请求适用于 Postman,但为啥它不适用于 ReactJS fetch?