About the front-end JS cross – domain some experience

why

If the requested domain name is different from the current domain name when the browser sends a request using XMLHttpRequest, the browser blocks the request for security. This is known as a cross-domain problem.

The solution

1. Jsonp implementation.

The jSONP principle is that the browser requests resource files without restriction, so it can request files from other domains. Here is a simple implementation. jsonp.js

let connect = require(".. /connect");
let handleSendData = require("./ajaxData").setUrlencodedData;
let process = new connect();

// Default parameters
const defaultConfig = {
    jsonp: 'callback'.prefix: "my_jsonp_callback_".data: {},
    success: function(result) {
        console.dir(result);
    },
    headers: {
        charset: "utf-8".type: "text/javascript"
    },
    url: "".fail: function() {},
    error: function(err) {
        console.dir(err); }};// Create a unique callback function number
let uniqueNumber = 1;

// Empty operation
let clear = function(data) {
    let js = data.js;
    let req = data.req;
    js.parentNode && js.parentNode.removeChild(js);
    delete window[req.data[req.jsonp]];
};

// The configuration before sending the request
let sendProcess = {
    init: function() {
        // Initialize the part that needs to be processed
        process.use(this.setSendData);
        process.use(this.setHeader);
        process.use(this.loadEvent);
        process.use(this.errorEvent);

    },
    // Set the script property
    setHeader: function(next, data) {
        let req = data.req;
        let js = data.js;
        let headers = req.headers;
        Object.keys(headers).forEach((key) = > {
            js.setAttribute(key, headers[key]);
        });

        next();
    },
    // Set the return event
    loadEvent: function(next, data) {
        let req = data.req;
        window[req.data[req.jsonp]] = function(cb) {
            req.success(cb);
            clear(data);
        };
        next();
    },
    // Set the failed event
    errorEvent: function(next, data) {
        let req = data.req;
        let js = data.js;
        js.onerror = (e) = > {
            req.error(e);
            clear(data);
        };
        next();
    },
    // Set the transfer value
    setSendData: function(next, data) {
        let req = data.req;
        // Set the return ruin function name to be unique each time so there is no cache problemreq.data[req.jsonp] = req.prefix + (++uniqueNumber); handleSendData(data); next(); }};let sendJsonp = function(data) {
    data = Object.assign({}, defaultConfig, data);
    let js = document.createElement("script");
    process.data.js = js;
    process.data.req = data;

    process.handle();
    let connectSymbol = "?";
    if (~data.url.indexOf("?")) {
        connectSymbol = "&";
    }
    js.src = `${data.url}${connectSymbol}${data.sendData}`;
    document.getElementsByTagName("head") [0].appendChild(js);
};
sendProcess.init();

module.exports = sendJsonp;
Copy the code

Here is how Node handles the JSONP request as part of the server, simply checking whether a parameter is present in a callback and returning it as a function name. response.js

const jsonp = {
    jsonpKey: "callback".isJsonp: function(req) {
        if (req.body[this.jsonpKey]) {
            return true;
        }
        return false;
    },
    handleJSONPsend: function(req, responseString) {
        let callbackName = req.body[this.jsonpKey];
        return `${callbackName}(${responseString}) `; }}; exports =module.exports = function(req, res, next) {
    res.sendJSON = function(data) {
        let response = {
            code: 200.data: data
        };
        let responseString = JSON.stringify(response);
        if (jsonp.isJsonp(req)) {
            responseString = jsonp.handleJSONPsend(req, responseString);
        }
        res.send(responseString);
    };

    next();
};

Copy the code

2 通过设置Access-Control-Allow-Origin

On the client side, we still send ajax requests using XHR objects as normal. The only thing to note is that we need to set our XHR property withCredentials to true, otherwise cookies will not pass through. Set xhr.withCredentials = true; For the server, you need to set the following two fields in the Response header: access-Control-allow-origin: Access-control-allow-credentials :true This allows us to request interfaces across domains. But a XHR object is but a simple request, a Preflighted request, and a Preflighted authentication request. Simple requests do not need to send OPTIONS sniffing requests, but can only send simple GET, HEAD, or POST requests, and cannot be customized HTTP Headers. But are known as Preflighted requests and authentication requests, XHR will first send an OPTIONS sniffing request, then XHR determines whether there is Access to the specified site based on the Access-Control-* header returned by the OPTIONS request, and decides whether to send the actual request. Therefore, when we check the network, we will find that the request is sent twice. Options: Query supported methods to query methods that specify resource support for the requested URL.