Lesson 18-Principles of Nine Cross-Origin Methods

Cross-Origin Resource Sharing (CORS) is a common requirement in modern web development. Due to security restrictions, browsers prevent frontend JavaScript scripts from making requests from one origin (protocol, domain, port) to another by default. To enable cross-origin requests, several methods can bypass this restriction. Below are nine common cross-origin techniques and their implementation principles.

JSONP (JSON with Padding)

Principle:

  • JSONP leverages the <script> tag to load remote resources and execute a callback function.
  • The client creates a <script> tag with a URL pointing to the target server’s API, including the callback function name as a query parameter.
  • The server returns JavaScript code that calls the client-specified callback function, passing data as an argument.

Example:

<script>
  function handleResponse(data) {
    console.log(data);
  }
</script>
<script src="https://example.com/api?callback=handleResponse"></script>

Server Response:

handleResponse({"name": "John", "age": 30});

Advantages:

  • Simple and compatible with older browsers.
  • Supports GET requests.

Disadvantages:

  • Does not support POST requests.
  • Poses security risks, such as vulnerability to XSS attacks.

CORS (Cross-Origin Resource Sharing)

Principle:

  • CORS is a mechanism based on HTTP headers that allows servers to specify which origins can access their resources.
  • The browser sends a preflight request (OPTIONS) to check if the server permits the cross-origin request.
  • If the server responds with appropriate CORS headers, the browser proceeds with the actual request.

Key HTTP Headers:

  • Access-Control-Allow-Origin: Specifies allowed origins.
  • Access-Control-Allow-Methods: Specifies allowed HTTP methods.
  • Access-Control-Allow-Headers: Specifies allowed custom headers.
  • Access-Control-Max-Age: Specifies the cache duration for preflight results.

Example:

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization

Advantages:

  • Supports all HTTP request types.
  • High security with server-controlled permissions.

Disadvantages:

  • Requires server-side configuration.
  • Preflight requests add network overhead.

Proxy Server

Principle:

  • A proxy server is set up within the same origin, and frontend requests are forwarded to the target server via this proxy.
  • The proxy handles cross-origin issues and returns the response to the frontend.

Example:

// Client
fetch('/proxy/https://example.com/api')
  .then(response => response.json())
  .then(data => console.log(data));

// Proxy Server (Node.js Example)
const express = require('express');
const axios = require('axios');
const app = express();

app.get('/proxy/:url', async (req, res) => {
  try {
    const response = await axios.get(req.params.url);
    res.json(response.data);
  } catch (error) {
    res.status(500).send(error.message);
  }
});

app.listen(3000, () => console.log('Proxy server running on port 3000'));

Advantages:

  • Resolves cross-origin issues without modifying the target server.
  • Allows additional request processing and optimization.

Disadvantages:

  • Increases server load and complexity.
  • May introduce performance bottlenecks.

WebSocket

Principle:

  • WebSocket is a full-duplex communication protocol that maintains a persistent connection between client and server.
  • WebSocket connections are not subject to the same-origin policy, enabling communication across different origins.

Example:

const socket = new WebSocket('wss://example.com/socket');

socket.onopen = () => {
  console.log('Connected to WebSocket server');
};

socket.onmessage = (event) => {
  console.log('Message from server:', event.data);
};

Advantages:

  • Supports bidirectional communication with high real-time performance.
  • Unaffected by same-origin policy.

Disadvantages:

  • Requires server support for the WebSocket protocol.
  • Best suited for real-time communication, not one-off requests.

postMessage API

Principle:

  • postMessage is an API for secure communication between different windows or iframes.
  • It allows parent and child pages (even from different origins) to exchange messages and receive responses.

Example:

<!-- Parent Page -->
<iframe id="childFrame" src="https://example.com/child.html"></iframe>

<script>
  const childFrame = document.getElementById('childFrame').contentWindow;

  // Send message to child page
  childFrame.postMessage('Hello from parent', 'https://example.com');

  // Listen for messages from child page
  window.addEventListener('message', (event) => {
    if (event.origin !== 'https://example.com') return;
    console.log('Message from child:', event.data);
  });
</script>

<!-- Child Page -->
<script>
  // Listen for messages from parent page
  window.addEventListener('message', (event) => {
    if (event.origin !== 'https://parent.com') return;
    console.log('Message from parent:', event.data);

    // Reply to parent page
    event.source.postMessage('Hello from child', event.origin);
  });
</script>

Advantages:

  • High security with origin verification via the origin parameter.
  • Suitable for communication between windows or iframes.

Disadvantages:

  • Limited to inter-page communication, not directly applicable to AJAX requests.

Nginx Reverse Proxy

Principle:

  • Nginx acts as a reverse proxy server, forwarding frontend requests to the target server.
  • Nginx handles cross-origin issues and returns responses to the frontend.

Example:

server {
  listen 80;
  server_name example.com;

  location /api/ {
    proxy_pass https://target-server.com/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    add_header Access-Control-Allow-Origin *;
  }
}

Advantages:

  • Resolves cross-origin issues without modifying the target server.
  • High performance, suitable for high-concurrency scenarios.

Disadvantages:

  • Requires Nginx setup and maintenance.
  • Increases system complexity.

CORS Proxy

Principle:

  • A third-party CORS proxy service (e.g., cors-anywhere) forwards frontend requests to the target server.
  • The proxy handles cross-origin issues and returns responses to the frontend.

Example:

fetch('https://cors-anywhere.herokuapp.com/https://example.com/api')
  .then(response => response.json())
  .then(data => console.log(data));

Advantages:

  • Quick and easy, no need to set up a proxy server.
  • Ideal for temporary testing and development environments.

Disadvantages:

  • Relies on third-party services, which may be unstable or insecure.
  • Not suitable for production environments.

DNS Prefetching and Subresource Integrity (SRI)

Principle:

  • DNS Prefetching resolves target domain DNS records in advance to reduce initial access latency.
  • Subresource Integrity (SRI) ensures the integrity of external resources, preventing man-in-the-middle attacks.

Example:

<!-- DNS Prefetching -->
<link rel="dns-prefetch" href="//example.com">

<!-- SRI -->
<script src="https://example.com/script.js"
        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
        crossorigin="anonymous"></script>

Advantages:

  • Improves performance by reducing initial access latency.
  • Enhances security by ensuring resource integrity.

Disadvantages:

  • Only applicable to static resources, not dynamic cross-origin requests.

Hashbang URL and HTML5 History API

Principle:

  • Hashbang URL and HTML5 History API enable frontend navigation without page reloads by modifying the URL’s hash or state.
  • These methods allow indirect cross-origin communication without direct cross-origin requests.

Example:

// Using Hashbang URL
window.location.hash = '#/page';

// Using HTML5 History API
history.pushState({}, '', '/page');

Advantages:

  • Suitable for specific scenarios like single-page applications (SPAs).
  • No server-side configuration required.

Disadvantages:

  • Limited to URL navigation, not a solution for actual cross-origin requests.
  • May impact SEO and user experience.
Share your love