2015-08-17 6 views
-3

При загрузке файла .xlsx запрос выполняется успешно, но мой обратный вызов ошибки ajax вызывает сообщение «parsererror - Invalid xml». Мое приложение запрашивает файл с сервера, который является прокси для получения этого файла с другого сервера.

На всех трех машинах, я установил следующее .htaccess:

AddType application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx 

Аякса вызов структурирован таким образом:

var attachment = { name="myfile.xlsx", 
        content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx", 
        id="resource_id_on_remote-server"} 

var path = '/path_to/attachment_file.php?' + $.param(attachment); 

$.ajax({ 
    type: "GET", 
    url: document.getElementById('attachment_download_frame').src = path, 
    success: function(xhrResponse) { 
    }, 
    error: function(xhrResponse, errmsg, error) { 
    //errmsg = "parsererror" 
    }, 
    complete: function() { 
    $('#spinner').spin("modal"); 
    } 
}); 

I Воронка вызов через скрытый iframe, какой actuall инициирует запрос.

файловый сервер, attachment_file.php запрашивает файл вложения от хост-сервера с «патроном» параметров JSon:

$id = filter_input(INPUT_GET, 'id'); 
    $contentType = filter_input(INPUT_GET, 'content_type'); 
    $name = filter_input(INPUT_GET, 'name'); 

    $url = REMOTE_BASE_URL . '/api/v1/attachment.json?'; 
    $url .= http_build_query(array('id' => $id, 'name' => $name, 'content_type' => $contentType)); 

    $curl = curl_init($url); 
    $headers = array(
     'Content-Type: ' . $contentType 
); 

    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); 
    curl_setopt($curl, CURLOPT_HTTPGET, true); 

    $response = curl_exec($curl); 
    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 

    curl_close($curl); 
    if ($response && in_array($httpCode, array(200, 201, 204))) { 
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 
    header('Content-Description: File Transfer'); 
    header("Content-Type: {$contentType}"); 
    header("Content-Disposition: attachment; filename={$name}"); 
    header("Expires: 0"); 
    header("Pragma: public"); 
    $fh = @fopen('php://output', 'w'); 
    fputs($fh, $response); 
    } else { 

    } 

Обратите внимание, как сохраняется «Content-Type». Я проверял, что это действительно установлено как: «application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx»

Сервер api, который вызывается, является приложением Rails и строит запрос на ресурс файла с использованием параметров принятый в:

def fetch_attachment options 
    url = REMOTE_URL + '/my_attachments/' + options[:id] 
    response = HTTParty.get(url) 
    if status? response 
     return response.parsed_response 
    else 
     return false; 
    end 
    return false; 
    end 

который использует HTTParty.get для запроса. В этот момент facepalm я буду исследовать, потерян ли тип контента в запросе HTTParty.

Кроме того, я задаю тип mime из параметров по определенным причинам.

ответ

1

Запрос GET в конце этого сообщения выводит только содержимое файла. Он не извлекает файл. Таким образом, содержимое файла отправляется обратно, возможно, не хватает необходимого шага кодирования с файлами MS, тем самым бросая (в этот момент, совершенно законную) ошибку парсера.

Это нехорошее решение в лучшем случае, но похоже, что конечные точки могут согласовывать содержимое и типы mime, чтобы предоставить файл конечному пользователю.

Мы, к сожалению, не имеем контроля над конечным запросом GET и можем получить доступ только к файлам данных в виде BLOB и доверять кодировке типа mime.

Смежные вопросы