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

时间:2011-10-28 18:02:30

标签: 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 =,也会尝试去某个不存在的地方。

所以...新想法是我只需创建一个表单onClick并提交。我的urlencoded路径作为参数POST没有问题 因为这注定要进入onClick,而我的onClick =使用双引号(这是我现在无法轻易改变的另一段巨大代码的一部分)我无法正确地避免转义。打破了并且没有在我的身份/姓名周围使用引号作为最后的手段,仍然没有骰子。

所以这就是我想出来的。这在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它的原始想法,但我已经浪费了一整天。实际上做了一个表,并尝试了每一个变化: 单个urlencoding,双重urlencoding编码,不同级别的编码进入与出现。 rawurlencode vs urlencode, AllowEncodedSlashes开/关

此时我猜测我使用mod_rewrite,拆分/生成原始查询路径作为数组和AllowEncodedSlashes的组合可能无法一起工作。

我也消除了按钮通过ajax发送给用户的事实,而这个按钮实际上最终是在jqgrid中。 这是我想简单地内联onClick on generation而不是

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

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

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

简单地用/替换/在编码之前并在工作之后将其更改回来但是我拒绝使用像这样的bug构建。

编辑: @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。

1 个答案:

答案 0 :(得分:0)

不要引用我这个,但我相信像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;
}