下载一个文件,但是发送一个POST来初始化它


Downloading a file, but sending a POST to initiate it

我在页面上有一个按钮,我通过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>';

look into AllowEncodedSlashes On for Apache
试过. .总是以%2Fvar%2Fadm%2Fmessages结束,即使在urldecode()或rawurldecode()之后,或者apache试图去一个不存在的地方,即使我的mod_rewrite在/将这些转换为q=.

. .新的思路是创建一个表单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()的答案是无用的。谢谢你。

编辑:


我愿意使用最初的想法,只是在窗口中进行urlencoding。外景剧本,但我已经浪费了一整天了。我做了一张表,试了所有的变体:单urlencoding,双urlencoding编码,不同层次的编码输入和输出。Rawurlencode vs urlencode;AllowEncodedSlashes开/关

在这一点上,我猜我的组合使用mod_rewrite,分裂/生成原始查询路径作为一个数组,和AllowEncodedSlashes只是可能不能一起工作。

我还消除了通过ajax将按钮发送给用户的事实,并且该按钮实际上在jqgrid中结束。这就是为什么我只想内联onClick生成而不是使用

$().click(function(){blah}); 

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

我之前所做的只是为每行生成一个uid,将其存储在会话变量中,并在用户访问/downloadLog/uid时将其解引用。这工作得很好,但出于性能原因,我喜欢将会话信息保持在4k以下,这样做很容易将其降低到16k。

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

EDIT: @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框架的路由类才能确定。

编辑

找出从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;
}