2016-12-01 3 views
1

У меня есть приложение Angular 1.x, которое ожидает получить загрузку бинарного файла (pdf) с помощью вызова $http.post(). Проблема в том, что я хотел бы получить сообщение об ошибке обработки, которое отправлено как json. Я могу сделать это с помощью конфигурацииМожет Угловой установить ответType после получения ответа?

headers: { 
    'Accept': 'application/pdf, application/json' 
} 

Проблема в том, у меня есть, чтобы установить responseType: 'arraybuffer', иначе PDF двоичный экранированы (или изменены таким образом, что он не загружается). Однако это предотвращает чтение или интерпретацию json.

Как я могу иметь оба?

Редактировать: Я собираюсь попытаться разъяснить; возможно, мое понимание неверно.

$http({ 
    method: 'POST', 
    url: "/myresource", 
    headers: { 
     'Accept': 'application/pdf, application/json' 
    }, 
    responseType: 'arraybuffer' 
}) 
.then(
    function(response) { 
     // handle pdf download via `new Blob([data])` 
    }, function(response) { 
     // pop up a message based on response.data 
    } 
) 

В случае, когда я возвращаюсь блок PDF данных и статус HTTP 200, первая функция обрабатывает ответ и предлагает пользователю сохранить файл. Однако, если состояние является ошибкой (422), значение response.data не определено. Я предполагаю, что это связано с тем, что responseType препятствует правильной обработке json.

Если я удаляю строку responseType, данные об ошибках считываются правильно, но при сохранении pdf некоторые из байтов файлов неправильны и эффективно повреждены. Я предполагаю, что это потому, что файл закодирован, потому что javascript ожидал строку.

+0

не отправлять ошибки сервера как данные успеха. отправьте их как ошибки. отправка 200 успешных сообщений с сообщением об ошибке для обработки только смущает потребителя API. – Claies

+0

@Claies, я не отправляю ошибку как статус 200 (это 422). –

+0

@georgeawg, я устанавливаю соответствующий тип контента для каждого ответа. –

ответ

5

Свойство XHR responseType не может быть изменено после того, как ответ был загружен. Но arraybuffer может быть декодирован и синтаксический анализ в зависимости от Content-Type:

var config = { 
    responseType: "arraybuffer", 
    transformResponse: jsonBufferToObject, 
    }; 

    function jsonBufferToObject (data, headersGetter, status) { 
     var type = headersGetter("Content-Type"); 
     if (!type.startsWith("application/json")) { 
     return data; 
     }; 
     var decoder = new TextDecoder("utf-8"); 
     var domString = decoder.decode(data); 
     var json = JSON.parse(domString); 
     return json; 
    }; 

    $http.get(url, config); 

Приведенный выше пример устанавливает XHR, чтобы возвращать arraybuffer и использует transformResponse функцию для обнаружения Content-Type: application/json и преобразовать его в случае необходимости.

DEMO on PLNKR

+0

Да, это то, что я искал (не понял). –

+0

AngularJS $ http использует [XHR API] (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest). [Новый API-интерфейс Fetch API] (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) может выполнять оба действия или изменять их на лету. – georgeawg

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