Blog Image

Fix Angular - Access to XMLHttpRequest from origin has been blocked by CORS policy:

Table of Contents

  1. Understanding CORS
  2. Setting up a Proxy in Angular (for Development)
  3. Configuring Angular to Use the Proxy
  4. Testing the Proxy Setup
  5. Troubleshooting Common Issues
  6. Fixing CORS Errors in Production

Understanding CORS

CORS (Cross-Origin Resource Sharing) is a security mechanism enforced by browsers that restricts web applications from making requests to a different origin (domain, protocol, or port) than the one from which the application was served. For example, if your Angular app is running on http://localhost:4200 and it tries to make a request to http://api.example.com, the browser will block this request unless the server at api.example.com explicitly allows it.

Why CORS Exists:

Common CORS Error Message:

Access to fetch at 'http://api.example.com/data' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Setting up a Proxy in Angular (for Development)

In this part of the tutorial, your’ll learn how to fix an CORS error in your development environment. Later on, you’ll learn how to fix CORS errors in production.

  1. Create a Proxy Configuration File:

    In the root directory of your Angular project (where angular.json is located), create a file named proxy.conf.json.

    touch proxy.conf.json
    
  2. Define Proxy Rules:

    Open proxy.conf.json and define the routes you want to proxy. For example, if your API is hosted at http://api.example.com, you can set up the proxy as follows:

    {
      "/api": {
        "target": "http://api.example.com",
        "secure": false,
        "changeOrigin": true,
        "logLevel": "debug",
        "pathRewrite": {
          "^/api": ""
        }
      }
    }
    

    Explanation of Configuration:

    • "/api": The context to match. All requests starting with /api will be proxied.
    • "target": The destination server where the API is hosted.
    • "secure": false: If the target is using HTTPS with self-signed certificates, set this to false. Otherwise, keep it true.
    • "changeOrigin": true: Changes the origin of the host header to the target URL.
    • "logLevel": "debug": Enables detailed logging for debugging purposes.
    • "pathRewrite": Rewrites the URL path. For example, /api/users becomes /users when forwarded to the target.

    Example Scenario:

    • Angular App: http://localhost:4200
    • API Endpoint: http://api.example.com/users
    • Proxy Request: http://localhost:4200/api/users → Proxied to http://api.example.com/users

Configuring Angular to Use the Proxy

  1. Modify angular.json:

    To instruct Angular’s development server to use the proxy configuration, you need to update the serve options in angular.json.

    {
      ...
      "projects": {
        "your-project-name": {
          ...
          "architect": {
            "build": { ... },
            "serve": {
              "builder": "@angular-devkit/build-angular:dev-server",
              "options": {
                "proxyConfig": "proxy.conf.json"
              },
              ...
            },
            ...
          }
        }
      }
      ...
    }
    

    Replace "your-project-name" with the actual name of your project.

  2. Alternative: Using Command-Line Option:

    If you prefer not to modify angular.json, you can specify the proxy configuration when starting the development server.

    ng serve --proxy-config proxy.conf.json
    

    Note: This method requires you to provide the --proxy-config flag each time you run ng serve.

Testing the Proxy Setup

  1. Start the Angular Development Server:

    If you configured the proxy in angular.json, simply run:

    ng serve
    

    If you prefer using the command-line option:

    ng serve --proxy-config proxy.conf.json
    
  2. Verify API Calls:

    • Open your browser and navigate to http://localhost:4200.
    • Open the browser’s developer tools (usually F12 or right-click > Inspect).
    • Go to the Network tab.
    • Ensure that API requests (e.g., /api/users) are being made.
    • Check that the requests are successfully proxied to the target API without CORS errors.
  3. Check the Terminal Logs:

    With "logLevel": "debug" in your proxy configuration, the terminal running ng serve will display detailed logs about the proxied requests. This can help verify that the proxy is working as intended.

    Example Log:

    [HPM] Proxying request /api/users to http://api.example.com/users
    

Troubleshooting Common Issues

While setting up a proxy in Angular is straightforward, you might encounter some common issues. Here are solutions to potential problems:

  1. Proxy Not Working:

    • Issue: API requests are still resulting in CORS errors.
    • Solution:
      • Ensure that the proxy configuration file (proxy.conf.json) is correctly referenced in angular.json or the ng serve command.
      • Verify that the context (/api in the example) matches the API calls in your Angular service.
      • Restart the development server after making changes to the proxy configuration.
  2. Path Rewriting Errors:

    • Issue: The backend API is not receiving the correct endpoint.
    • Solution:
      • Check the pathRewrite configuration in proxy.conf.json. Ensure that the rewrite rules correctly transform the proxied path.
      • For example, if your Angular app requests /api/users and the backend expects /users, the pathRewrite should be { "^/api": "" }.
  3. HTTPS Issues:

    • Issue: Proxying to an HTTPS backend with self-signed certificates fails.
    • Solution:
      • Set "secure": false in the proxy configuration to allow proxying to an HTTPS server with self-signed certificates.
      • Caution: This should only be used in development environments.
  4. CORS Errors Persisting:

    • Issue: Despite setting up the proxy, CORS errors still occur.
    • Solution:
      • Ensure that all API calls in your Angular application use the proxy context (e.g., /api) instead of the full backend URL.
      • Double-check the target URL in proxy.conf.json for correctness.
      • Make sure there are no typos or syntax errors in the proxy configuration file.

Fixing CORS Errors in Production

Important Note: The proxy configuration provided in this tutorial is intended only for development purposes and will not work once the application is deployed. In a production environment, using a development proxy is not feasible because the Angular development server is not present, and deploying such a proxy could introduce security vulnerabilities and performance issues.

To resolve CORS errors in production, you should implement solutions that are secure, reliable, and maintainable. One approach is to use a dedicated CORS proxy service like corsproxy.io. This service allows you to bypass CORS restrictions by prefixing your API requests with the proxy URL. For example, to access https://example.com, you would use:

https://corsproxy.io/?url=https://example.com

Use CorsProxy.io in Angular

// api.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  private apiUrl = 'https://example.com/api'; // Use the proxy context

  constructor(private http: HttpClient) {}

  getUsers(): Observable<any> {
    return this.http.get(`https://corsproxy.io/?url=${encodeURIComponent(this.apiUrl)}/users`);
  }

  // Add more API methods as needed
}

By thoughtfully implementing CORS handling in your production environment, you can ensure that your Angular application communicates securely and efficiently with your backend services without relying on development-specific proxies.

Create a free Account to fix CORS Errors in Production

Say goodbye to CORS errors and get back to building great web applications. It's free!

App screenshot