简体   繁体   English

是否可以使用 Javascript 打开一个新窗口,将 POST 参数传递到新窗口,同时将请求作为 application/json 传递?

[英]Is it possible to use Javascript to open a new window, POST paramaters to the new window, while passing the request as application/json?

I have a JavaScript-based browser client application that deals with a lot of state data.我有一个基于 JavaScript 的浏览器客户端应用程序,它处理大量状态数据。 Occasionally that data must be gathered together into a well-formed object and dumped to a new window that accepts that data for processing.有时,必须将数据收集到一个格式良好的对象中,然后转储到接受该数据进行处理的新窗口中。

A solution I have that already functions is the following: when the data needs to be sent, the target URL and data are passed to what is effectively this function, which leverages a virtual form element that submits the data:我已经拥有的一个解决方案如下:当需要发送数据时,目标 URL 和数据被传递给这个函数,它利用了一个提交数据的虚拟form元素:

function sendJson(targetUrl, jsonData) {
    let form = document.createElement("form");
    form.method = "POST";
    form.action = targetUrl;
    form.target = '_blank';

    let element = document.createElement("input");
    element.value = JSON.stringify(jsonData);
    element.name = 'json';
    form.appendChild(element);

    document.body.appendChild(form);
    form.submit();
    form.parentNode.removeChild(form);
}

This effectively crams the well-formed data into a single form field and re-encodes it as application/x-www-form-urlencoded .这有效地将格式良好的数据填充到单个表单字段中,并将其重新编码为application/x-www-form-urlencoded A PHP script awaits on the other end that extracts the data more or less like this:一个 PHP 脚本在另一端等待,它或多或少地像这样提取数据:

$json_data = json_decode($_POST['json'], true);

This method has some upsides I like, namely:这种方法有一些我喜欢的优点,即:

  • The new window has a distinct URL from the parent新窗口具有与父窗口不同的 URL
  • The network request belongs to the new window, not the parent window that opened it网络请求属于新窗口,而不是打开它的父窗口

These mean I can re-POST the same request over and over by simply refreshing the window and re-sending POST variables, which comes in handy.这意味着我可以通过简单地刷新窗口并重新发送 POST 变量来一遍又一遍地重新 POST 相同的请求,这很方便。

What I do not like is that the data over the wire is URL encoded now.我不喜欢的是现在通过网络传输的数据是 URL 编码的。 My network debugging tools that neatly display JSON-hierarchical data fail to parse it and instead just dump out what it now is -- a single, excessively long string full of encoded symbols.我的网络调试工具整齐地显示 JSON 分层数据无法解析它,而是只是转储它现在的样子——一个充满编码符号的过长的单个字符串。 If I ever need to inspect this, I have to run it through a URL decoder and a JSON prettifier, which I find incredibly inconvenient.如果我需要检查它,我必须通过 URL 解码器和 JSON 修饰符来运行它,我觉得这非常不方便。 It would be greatly beneficial if I could send the request as application/json instead of application/x-www-form-urlencoded .如果我可以将请求作为application/json而不是application/x-www-form-urlencoded发送,那将是非常有益的。

So instead, I tried a solution like this, utilizing window.open() :所以相反,我尝试了一个这样的解决方案,利用window.open()

function sendJson(targetUrl, jsonData) {
    fetch(targetUrl, {
        method: 'POST',
        headers: {
            'Content-type': 'application/json',
            'Accept': 'text/html'
        },
        body: JSON.stringify(jsonData)
    })
        .then(response => response.text())
        .then(text => {
            let newWin = window.open(targetUrl, '_blank');
            newWin.document.open();
            newWin.document.write(text);
            newWin.document.close();
        });
}

And PHP on the other side picks it up like:而另一边的 PHP 则是这样处理的:

$json_data = json_decode(file_get_contents('php://input'), true);

Now the JSON is going over the wire in its native format, solving the encoding problem.现在 JSON 以其原生格式通过网络,解决了编码问题。 But now the call to window.document.open() resets the URL of the new window to the URL of the parent.但是现在对window.document.open()的调用会将新窗口的 URL 重置为父窗口的 URL。 If the new window is refreshed, it redirects to the parent window.如果新窗口被刷新,它会重定向到父窗口。 And even if that wasn't the case, there's no POST data to refresh, since the request "belongs" to the parent window.即使不是这种情况,也没有要刷新的 POST 数据,因为请求“属于”父窗口。 The data has simply been streamed to the parent and written to the new window manually.数据已简单地流式传输到父窗口并手动写入新窗口。

What I'm left with are two functional, but less than ideal, solutions.我剩下的是两个功能强大但不太理想的解决方案。 My question is, does a solution exist that gives me all of the features I want?我的问题是,是否存在可以提供我想要的所有功能的解决方案?

  • Pure JavaScript implementation (no libraries, preferably no DOM trickery)纯 JavaScript 实现(没有库,最好没有 DOM 技巧)
  • POST data sent as application/json over the wire POST 数据作为application/json通过网络发送
  • Request opens in a new window/tab请求在新窗口/选项卡中打开
  • New window points to a URL distinct of parent window新窗口指向与父窗口不同的 URL
  • New window can be re-POSTed by refreshing that window可以通过刷新该窗口来重新发布新窗口

No.不。

Only fetch and XMLHttpRequest can be used to make a request with an application/json body, and the response to those can only be handled with JS.只有fetchXMLHttpRequest可用于使用application/json主体发出请求,并且只能使用 JS 处理对它们的响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM