Angular HttpClient ResponseType错误:Ionic/Angular仅允许JSON响应
Hey there, let's tackle that frustrating error you're seeing when trying to download a PNG via API in Ionic/Angular. The message "For some reason only a response of type json is allowed..." almost always boils down to how your HTTP requests are configured—either the default response type is stuck on JSON, or an interceptor is forcing every response to parse as JSON. Here's how to fix it:
1. Explicitly Set the Response Type in HttpClient
Angular's HttpClient defaults to expecting JSON responses, so you need to tell it to handle binary data (like PNGs) instead. Use responseType: 'blob' (or 'arraybuffer') when making your request:
import { HttpClient } from '@angular/common/http'; import { Component } from '@angular/core'; @Component({ selector: 'app-image-download', templateUrl: './image-download.component.html' }) export class ImageDownloadComponent { constructor(private http: HttpClient) {} downloadPngImage() { const apiEndpoint = 'https://your-api-url.com/image.png'; this.http.get(apiEndpoint, { responseType: 'blob' }) .subscribe({ next: (blob) => { // Create a download link for the blob const downloadUrl = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = downloadUrl; link.download = 'my-image.png'; document.body.appendChild(link); link.click(); // Clean up window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(link); }, error: (err) => { console.error('Failed to download image:', err); } }); } }
2. Check for Interceptors Forcing JSON Responses
If you're using an HTTP interceptor (e.g., for auth headers), it might be overriding the response type for all requests—including your image download. Update the interceptor to skip processing requests that need binary responses:
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable() export class AuthInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> { // Skip interception for blob/arraybuffer requests or PNG URLs if (req.responseType === 'blob' || req.responseType === 'arraybuffer' || req.url.includes('.png')) { return next.handle(req); } // Your regular interceptor logic (e.g., adding auth tokens) const modifiedRequest = req.clone({ setHeaders: { Authorization: `Bearer ${localStorage.getItem('authToken')}` } }); return next.handle(modifiedRequest); } }
3. If Using Ionic Native HTTP Plugin
If you're using @ionic-native/http instead of Angular's built-in HttpClient, adjust the response type in the request options:
import { HTTP } from '@ionic-native/http/ngx'; import { Component } from '@angular/core'; @Component({ selector: 'app-image-download', templateUrl: './image-download.component.html' }) export class ImageDownloadComponent { constructor(private httpNative: HTTP) {} downloadPngNative() { const apiEndpoint = 'https://your-api-url.com/image.png'; this.httpNative.get(apiEndpoint, {}, {}, { responseType: 'blob' }) .then((data) => { const blob = new Blob([data.data], { type: 'image/png' }); // Same download logic as before const downloadUrl = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = downloadUrl; link.download = 'my-image.png'; document.body.appendChild(link); link.click(); window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(link); }) .catch((err) => { console.error('Native HTTP error:', err); }); } }
Key Takeaway
The main issue is that your app is trying to parse a binary PNG as JSON, which fails. By explicitly setting the response type to blob or arraybuffer, and making sure interceptors don't interfere, you should be able to download the PNG without that error.
内容的提问来源于stack exchange,提问作者Klitz

