php - 下载文件,但发送 POST 以启动它

标签 php jquery post download inline

我在页面上有一个按钮,它带有我通过 Jquery 动态设置的 onClick。

该按钮开始下载文件。 我正在使用 mod_rewrite 来转换 http://somesite.com/blah1/blah2/blah3/blah4进入 index.php&q=$1

然后我访问 q,在/上拆分,我得到任何用户请求的路径作为数组。
效果很好,但我无法将编码路径作为我的变量之一发送:

<?php
    $html = '<button onClick="window.location = \'' . SITE_URL . 'downloadLog/' . urlencode($some_path) . ">Click me</button>';

研究了 Apache 的 AllowEncodedSlashes On。
试过了.. 即使在 urldecode() 或 rawurldecode() 之后,总是以 %2Fvar%2Fadm%2Fmessages 结束,或者即使我的 mod_rewrite 打开/将它们转换为 q=,apache 也试图去一个不存在的地方。

所以.. 新想法是我将只创建一个 onClick 表单并提交它。 POST 将我的 urlencoded 路径作为参数没有问题。
因为这注定要进入 onClick,而我的 onClick= 使用双引号(这是另一大段代码的一部分,我现在无法轻易更改)我认为我无法正确转义。崩溃了,没有在我的 id/name 周围使用引号作为最后的手段,仍然没有骰子。

这就是我想出的。这不会在 Firebug 中出错,但我也没有看到 POST 发生。

function get_inline_post($a) {
    $output .= 'this_form = $(\'<form submit=' . SITE_URL . $a['submit'] . ' ></form>\').html(\'\')';
    unset($a['submit']);
    foreach ( $a as $key => $value ) {
        $output .= '.append(\'<input id=' . $key . ' name=' . $key . ' type=hidden>\')';
    }
    $output .= ';';
    foreach ($a as $key => $value ) {   
        $output .= '$(\'#' . $key . '\').val(\'' . rawurlencode($value) . '\');';
    }
    $output .= 'this_form.submit();';
    return $output;
}

如果给定正确的变量,最终会在我的 onClick 中构建它:

<button class="ui-corner-all" 
    onClick="
        this_form = $('<form submit=/downloadHostLog/messages></form>').html('').append('<input id=link_hcmdb_id name=link_hcmdb_id type=hidden >').append('<input id=added_path name=added_path type=hidden >');
        $('#link_hcmdb_id').val('046345D4771C4D3FBD2EF33CBE038028');$('#added_path').val('var%2Fadm');this_form.submit();
    " 
    title="Kill me now" type="button">
    <span class="ui-icon ui-icon-copy"></span>
</button>

请记住,我正在尝试在此处启动下载,因此使用 .post() 的答案是无用的。谢谢。

编辑:
我愿意使用最初的想法,即在 window.location 脚本中对其进行 urlencoding,但我已经在这上面浪费了一整天了。实际上制作了一张 table 并尝试了以下每一种变化: 单 urlencoding,双 urlencoding 编码,不同级别的编码输入和输出。 rawurlencode 与 urlencode, 允许编码斜杠开/关

在这一点上,我猜测我使用 mod_rewrite、拆分/以将原始查询路径生成为数组以及 AllowEncodedSlashes 的组合可能无法一起工作。

我还消除了按钮通过 ajax 发送给用户的事实,并且该按钮实际上以 jqgrid 结束。 这是我想简单地在生成时内联 onClick 而不是做

的部分原因
$().click(function(){blah}); 

对于每个结果行,因为每一行都有 5 个不同的参数,除了我在这里显示的参数之外,出于安全目的,这些参数对每一行都是唯一的……所以我最终调用了绑定(bind) 50-500 次,这非常缓慢。

我之前所做的只是为每一行生成一个 uid,将其存储在 session 变量中,并在用户访问/downloadLog/UID 时取消引用它。这也很有效,但出于性能原因,我喜欢将我的 session 信息保持在 4k 以下,这样做很容易将它提高到 16k。

简单地用 | 替换/在编码并在工作后将其改回之前,但我拒绝求助于构建这样的错误。

编辑: @dqhendricks 我当前的 mod_rewrite 语句:

    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)? index.php?q=$1 [L,QSA]

相应的 php 处理:

foreach ( preg_split('/\//',$_GET['q']) as $key => $value)
{
    $g[$key] = urldecode($value);
}

鉴于以上情况,我尝试了 AllowEncodedSlashes On 和 Off。没有人允许将/blah/blah/%2F%var%2Fadmin/blah 定向到 index.php。得到 404。

最佳答案

不要在这方面引用我的话,但我相信像 Zend 这样的框架只是将所有内容重定向到 index.php(没有 GET 请求变量),然后从 $_SERVER['ORIG_PATH_INFO']* 之类的东西中获取请求数据。这会在解码 url 之前为您提供请求数据。然后您可以拆分请求字符串,并自行解码每个变量。

*不确定,但像这样。必须查看 Zend Framework 的路由类才能确定。

编辑

挖出从 zend 框架获取请求 uri 的代码。 Zend_Controller_Request_Http 类的一部分,但你明白了。

public function setRequestUri($requestUri = null)
{
    if ($requestUri === null) {
        if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch
            $requestUri = $_SERVER['HTTP_X_REWRITE_URL'];
        } elseif (
            // IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem)
            isset($_SERVER['IIS_WasUrlRewritten'])
            && $_SERVER['IIS_WasUrlRewritten'] == '1'
            && isset($_SERVER['UNENCODED_URL'])
            && $_SERVER['UNENCODED_URL'] != ''
            ) {
            $requestUri = $_SERVER['UNENCODED_URL'];
        } elseif (isset($_SERVER['REQUEST_URI'])) {
            $requestUri = $_SERVER['REQUEST_URI'];
            // Http proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
            $schemeAndHttpHost = $this->getScheme() . '://' . $this->getHttpHost();
            if (strpos($requestUri, $schemeAndHttpHost) === 0) {
                $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
            }
        } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI
            $requestUri = $_SERVER['ORIG_PATH_INFO'];
            if (!empty($_SERVER['QUERY_STRING'])) {
                $requestUri .= '?' . $_SERVER['QUERY_STRING'];
            }
        } else {
            return $this;
        }
    } elseif (!is_string($requestUri)) {
        return $this;
    } else {
        // Set GET items, if available
        if (false !== ($pos = strpos($requestUri, '?'))) {
            // Get key => value pairs and set $_GET
            $query = substr($requestUri, $pos + 1);
            parse_str($query, $vars);
            $this->setQuery($vars);
        }
    }

    $this->_requestUri = $requestUri;
    return $this;
}

关于php - 下载文件,但发送 POST 以启动它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7933065/

相关文章:

php - 在模板中将代码与布局分开

php - Codeigniter UPS API 集成 - 交货日期

php - 带有 php 的动态导航栏工作正常但是当尝试使用 foreach 获取错误输入子菜单时

jquery - 如何才能让这个条形码正确显示

grails - 使用 POST 请求重定向

C#:带有 POST 参数的 HttpClient

javascript - 从 php 循环获取值并在 keyup 上乘以这些值

php - 如何在 vueJS 中使用 summernote?错误 :summernote is not a function

php - 关于将 JavaScript 生成的内容发布到文件以供下载为 CSV 的建议

rest - 使用 Flutter 将图像发布到 Web 服务