阿里云主机折上折
  • 微信号
Current Site:Index > Cross-domain request handling

Cross-domain request handling

Author:Chuan Chen 阅读数:20478人阅读 分类: JavaScript

Basic Concepts of Cross-Origin Requests

Cross-origin requests refer to browser-imposed security restrictions that prevent scripts loaded from one origin from interacting with resources from another origin. The same-origin policy requires that the protocol, domain, and port must be identical to be considered same-origin. When any of these three elements differ, a cross-origin issue arises. For example:

  • http://a.com requesting https://a.com (different protocol)
  • http://a.com requesting http://b.com (different domain)
  • http://a.com:80 requesting http://a.com:8080 (different port)

Common Cross-Origin Solutions

JSONP

JSONP leverages the fact that <script> tags are not restricted by the same-origin policy. It dynamically creates a script tag, passing a callback function name as a parameter to the server, which then returns data wrapped in a call to that function.

function handleResponse(data) {
  console.log('Received data:', data);
}

const script = document.createElement('script');
script.src = 'http://example.com/api?callback=handleResponse';
document.body.appendChild(script);

CORS (Cross-Origin Resource Sharing)

CORS is a standard cross-origin solution supported by modern browsers. Servers declare which origins are allowed to access resources by setting response headers.

// Server-side configuration
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

Proxy Server

A same-origin backend server forwards requests to bypass the browser's same-origin policy.

// Frontend requests same-origin server
fetch('/api/proxy', {
  method: 'POST',
  body: JSON.stringify({
    url: 'http://target-domain.com/api'
  })
})

// Backend Node.js example
app.post('/api/proxy', async (req, res) => {
  const { url } = req.body;
  const response = await axios.get(url);
  res.json(response.data);
});

Preflight Mechanism for Complex Requests

For HTTP methods that may have side effects on server data (e.g., PUT, DELETE), browsers first send an OPTIONS request for preflight.

// Preflight request example
fetch('http://api.example.com/data', {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/json',
    'X-Custom-Header': 'value'
  },
  body: JSON.stringify({ key: 'value' })
});

Servers must properly handle OPTIONS requests:

app.options('/data', (req, res) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'PUT');
  res.header('Access-Control-Allow-Headers', 'Content-Type, X-Custom-Header');
  res.sendStatus(204);
});

Credential Issues in Cross-Origin Requests

By default, cross-origin requests do not send credentials like cookies. Special settings are required:

// Frontend setting
fetch('http://api.example.com/data', {
  credentials: 'include'
});

// Server-side setting
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Origin', 'http://your-domain.com'); // Cannot be *

WebSocket Cross-Origin Handling

The WebSocket protocol inherently supports cross-origin, but servers can decide whether to accept connections from specific origins.

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

// Server-side (Node.js + ws library)
const WebSocket = require('ws');
const wss = new WebSocket.Server({
  verifyClient: (info, done) => {
    const origin = info.origin;
    if (origin === 'http://allowed-domain.com') {
      done(true);
    } else {
      done(false, 401, 'Unauthorized');
    }
  }
});

Cross-Origin Image Resource Handling

Canvas operations on cross-origin images require special handling:

const img = new Image();
img.crossOrigin = 'Anonymous'; // Request CORS permission
img.onload = function() {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  // Now it's safe to manipulate the canvas
};
img.src = 'http://example.com/image.jpg';

Cross-Origin Font Loading

Web font files are also subject to same-origin policy restrictions. CORS headers must be set on the server:

@font-face {
  font-family: 'MyFont';
  src: url('http://example.com/font.woff') format('woff');
  font-display: swap;
}

Server response must include:

Access-Control-Allow-Origin: *

Error Handling for Cross-Origin AJAX Requests

When cross-origin requests fail, browsers provide limited error information, so special attention is needed for error handling:

fetch('http://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .catch(error => {
    console.error('Fetch error:', error);
    // Note: Detailed error information is unavailable for cross-origin requests
  });

Cross-Origin Solutions for Local Development

Common solutions during development:

  1. Disable browser security policies (development only)

    google-chrome --disable-web-security --user-data-dir=/tmp/chrome
    
  2. Use development server proxy

    // vite.config.js
    export default {
      server: {
        proxy: {
          '/api': {
            target: 'http://api.example.com',
            changeOrigin: true,
            rewrite: path => path.replace(/^\/api/, '')
          }
        }
      }
    }
    

Performance Optimization for Cross-Origin Requests

  1. Preload CORS resources:

    <link rel="preconnect" href="https://api.example.com">
    <link rel="preload" href="https://api.example.com/data.json" as="fetch" crossorigin>
    
  2. Combine requests to reduce preflight frequency

  3. Cache CORS preflight results:

    Access-Control-Max-Age: 86400
    

Cross-Origin Handling in Special Scenarios

postMessage for Cross-Document Communication

// Sender
const popup = window.open('http://other-domain.com');
popup.postMessage('Hello', 'http://other-domain.com');

// Receiver
window.addEventListener('message', event => {
  if (event.origin !== 'http://your-domain.com') return;
  console.log('Received message:', event.data);
});

Cross-Origin iframe Communication

// Parent page
document.getElementById('iframe').contentWindow.postMessage('Hello', 'http://child-domain.com');

// Inside iframe
window.parent.postMessage('Response', 'http://parent-domain.com');

Cross-Origin Restrictions for Browser Storage

  1. localStorage and IndexedDB follow same-origin policy
  2. Shared Workers can be used cross-origin with limitations
  3. Service Worker scope restrictions
// Explicitly define scope when registering Service Worker
navigator.serviceWorker.register('/sw.js', {
  scope: '/app/' // Can only control requests under /app/
});

Cross-Origin Handling in Modern Frontend Frameworks

Proxy Setup in React

// setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://api.example.com',
      changeOrigin: true,
    })
  );
};

Cross-Origin Configuration in Vue CLI

// vue.config.js
module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://api.example.com',
        ws: true,
        changeOrigin: true
      }
    }
  }
}

Security Considerations for Cross-Origin Requests

  1. Use Access-Control-Allow-Origin: * with caution
  2. Validate the origin of all cross-origin requests
  3. Restrict allowed HTTP methods
  4. Implement CSRF protection for sensitive operations
// Example middleware to check Origin header
app.use((req, res, next) => {
  const allowedOrigins = ['http://site1.com', 'http://site2.com'];
  const origin = req.headers.origin;
  
  if (allowedOrigins.includes(origin)) {
    res.header('Access-Control-Allow-Origin', origin);
  }
  
  next();
});

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

上一篇:JSONP原理

下一篇:对话框方法

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.