【问题标题】:API add Location Header and 302API 添加 Location Header 和 302
【发布时间】:2018-03-12 01:57:42
【问题描述】:

我使用一个简单但相当长的查询字符串请求编写了一个 API。 请求者可以指定 XML 或 HTML 响应。

收到查询并处理数据。 HTML 只是简单地回显一个响应。为了避免冗余代码,我使用 JavaScript 重定向来打开和处理 XML。看起来像这样:

$QString = '';
foreach($XMLItems as $key => $value)
{
   $QString .= $key.'^'.$value.'|';
}
$QString = substr($QString,0,-1);
Redirect('XMLProcess.php?Q='.$QString);

Redirect() 是一个运行 javascript 的简单函数:

function Redirect($n)
{
    die("<script type=\"text/javascript\">window.location='$n';</script>");
}

XML 结构如下所示:

<?php
    $dom = new DOMDocument("1.0");
    header ("Content-Type:text/xml");
    $QArray = explode('|',$_REQUEST[Q]);
    foreach($QArray as $value)
    {
       $x = explode('^',$value);
       $XMLItems[$x[0]] = $x[1];
    }

    $root = $dom->createElement("Data");
    $dom->appendChild($root);
    foreach($XMLItems as $key => $value)
    {
       $key = $dom->createElement($key);
       $root->appendChild($key);
       $variable = $dom->createTextNode($value);
       $key->appendChild($variable);
    }
    echo $dom->saveXML();
?>

我对 API 以及有人可能在接收端使用什么一无所知。我有一个客户要求 302 重定向和位置标头。我假设我的 Redirect() 函数可能会关闭他的软件,但我真的不知道。当然,我不能立即重定向到 XML 文件,因为需要先处理传入的数据。因此,我试图在不将处理复制到第二个文件中的情况下,围绕客户的需求进行思考。而且,由于我一无所知,重定向可能不是问题,无论如何。

【问题讨论】:

  • 就在死前,发出header('Location: sameurlasthejavascript');。这告诉浏览器进行重定向,并且几乎每个客户端都会遵守。 Thw Javascript 正文可能会保留作为后备。
  • 恐怕这会失败,这就是我使用 JavaScript 的原因。在重定向之前的处理中,有几个包含,其中一个包含来自 AS400 API 的请求数据。
  • 我不太理解,但如果你说它不会因为已经发送数据而导致,那么使用 ob_start 和朋友以正确的顺序捕获和输出。
  • 从来没有考虑过。不过,仍然不确定这是否是一个答案
  • 我需要看具体的代码来回答这个问题,但听起来你必须走各种弯路才能促进多模式输出。就像我在回答中所说的那样,这感觉很糟糕。最好将计算部分重构为它自己的帮助程序,并让 HTML 和 XML 前端发出与它们相关的任何内容。这样做可以避免所有这些重定向和 ob_ 业务。

标签: php xml api


【解决方案1】:

要发出 302 重定向(或任何状态码),您需要使用 header。根据文档:

第二种特殊情况是“Location:”标头。它不仅将此标头发送回浏览器,而且还会向浏览器返回一个 REDIRECT (302) 状态码,除非已经设置了 201 或 3xx 状态码。

实现如下:

function Redirect($n)
{
    header("Location: $n");
    exit(0);
}

如 cmets 中所述,由于您的脚本在调用 Redirect 之前发出输出,因此您需要使用 ob_start(和朋友)来捕获该输出并在发送标头后发出它:

ob_start();
// ...
$QString = '';
foreach($XMLItems as $key => $value)
{
   $QString .= $key.'^'.$value.'|';
}
$QString = substr($QString,0,-1);
Redirect('XMLProcess.php?Q='.$QString);

function Redirect($n)
{
    header("Location: $n");
    $contents = ob_get_clean();
    // echo $contents; // if you want or need to
    // you might also consider leaving this, but clients will
    // honor the 302 before executing any Javascript
    die("<script type=\"text/javascript\">window.location='$n';</script>");
}

所有这些都表明,代码感觉很笨拙。如果可能,请考虑重构 HTML 和 XML 版本,以便代码的主要工作在包含的帮助程序中完成,而 HTML 和 XML“前端”只专注于以所需格式呈现输出。

【讨论】:

    猜你喜欢
    • 2014-03-03
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    • 2019-05-10
    • 2017-08-13
    • 2014-03-14
    • 1970-01-01
    相关资源
    最近更新 更多