preface

  • Whether it is Ajax requests, canvas rendering, etc., there may be a problem – cross domain
  • Cross-domain is affected by the same origin policy of the browser
  • We also often encounter cross-domain problems, which make us have a certain impact on the implementation of many functions, let’s look at the following, how to solve the cross-domain problem
  • Complete album Demo – album

Front and back end interaction issues – cross domain

Browser Same-origin Policy

  • The same origin policy is a security function of the browser. Client scripts from different sources cannot read or write resources from each other without explicit authorization
  • The same origin policy is a behavior of the browser to protect local data from being contaminated by data retrieved by JavaScript code. Therefore, the same origin policy intercepts data received from the client. That is, the request is sent and the server responds, but the browser cannot receive the request
  • Source: protocol, domain name, and port number

Import resources that are not affected by the same origin policy

  • <script></script>,<img/>,<link></link>,<iframe></iframe>src

plan

  • jsonp
  • CORS addresses cross-domain
  • Proxy-server proxy requests

jsonp

  • jsonp – JSON width Padding
  • Jsonp principle – through<script></script>Features that are not affected by the same origin policy are implemented across domains

Simple to use

  • Back-end Node-koa
router.get('/getAjax'.ctx= > {
    // Return browser executable js code directly
    ctx.body = 'var a = 123';
});
Copy the code
  • The front end
<script src="http://127.0.0.1:1000/getAjax"></script>
<script>
    console.log(a); / / 123
</script>
Copy the code
  • This raises some new problems
    • Variable name contamination
    • Interaction is about communication, I send data to you, you send data back to me, it’s just JS, it doesn’t make any sense

Create script implementation requests dynamically

  • Let’s look at what we did beforeSimple to useProblems arise for JSONPscriptmodified
  1. useparamsqueryforClient -> BrowserData transmission of
  2. Dynamically created based on requirementsscript
  3. Asynchronous issues – Requests take time, so it is possible that later the required data is not loaded but you use it, causing an error
const btn = document.querySelector('button');
btn.onclick = () = > {
    const jsonp = document.createElement('script');
    jsonp.src = ` http://127.0.0.1:3000/getAjax `;
    document.head.appendChild(jsonp);
    // Avoid asynchrony issues and wait for onload
    jsonp.onload = () = > {
        console.log(a); }}Copy the code
  1. Onload doesn’t seem like a problem, but it’s kind of silly, so we can change it with a callback, pass the method name of the callback to the background, and then the back end goes back and executes js, okay
  • Back-end Node-koa
router.get('/getAjax'.ctx= > {
    const { cb, name } = ctx.query;
    ctx.body = `${cb}({
        name: '${name}',
        age: 20
    })`;
});
Copy the code
  • The front end
const btn = document.querySelector('button');
btn.onclick = () = > {
    const jsonp = document.createElement('script');
    jsonp.src = ` http://127.0.0.1:3000/getAjax? Name = zhang SAN & cb = cbFn `;
    document.head.appendChild(jsonp);
}

function cbFn(options) {
    console.log(options);
}
Copy the code

Typical example – Baidu search

  • Baidu interface
https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=hello&cb=succFn
Copy the code
  • Wd – Search for keywords
  • Cb – callback

Problems with JSONP

  • Can only be GET requests
  • Security issues

CORS cross-domain Settings

  • Cross-origin Resource Sharing (CORS) is a specification of the browser technology to avoid the same origin policy of the browser
  • This setting requires backend coordination
  • In effect, the back end returns data with a special header

Access-Control-Allow-Origin

  • When our browser sends a request via Ajax, if the request comes from a different source, the browser will look to see if there is one in the request headerAccess-Control-Allow-OriginField, and whether the current field is within the value of that field,
  • If true, the data is trusted and the response data is received
  • Otherwise refuse to accept
  • Back-end node-koa
ctx.set('Access-Control-Allow-Origin'.'http://127.0.0.1:8080'); // Only http://127.0.0.1:8080 can be accessed
ctx.set('Access-Control-Allow-Origin'.The '*'); // * is a wildcard character, indicating that any domain name can be accessed
Copy the code

Set the CORS header information

  • When CORS requests,XMLHttpRequestThe object’sgetResponseHeader()You can only get six basic fields:Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma
  • If you want to get the other fields, you have to be inAccess-Control-Expose-HeadersSpecify the inside
  • We also need to go through two special header Settings
    1. Access-Control-Allow-Headers– Allows requset to set the header
    2. Access-Control-Expose-Headers– Allows the client to obtain the header key
  • Back-end node-koa
ctx.set({
    'Access-Control-Allow-Origin': 'http://127.0.0.1:8080'.'Access-Control-Allow-Headers': 'Authorization'.'Access-Control-Expose-Headers': 'Authorization'
});
Copy the code

Preview the request

  • When a cross-site request is made, even if the server has access-Control-Allow-Origin set, a non-simple request will fail because a pre-check request will be made before a formal request is made

  • Requests that require prechecking must first issue a prechecking request to the server using the OPTIONS method to know whether the server will allow the actual request

  • The use of pre-checked requests prevents cross-domain requests from having an unexpected impact on the server’s user data

  • Simple request – Conditions met:

    • method

      1. GET
      2. POST
      3. HEAD
    • In addition to headers that are automatically set by the User Agent (such as Connection, user-Agent, and other headers that are defined in the Fetch specification to disable header names), fields that are allowed to be set artificially are the set of CORS safe header fields defined by the Fetch specification. The set is:

      1. Accept
      2. Accept-Language
      3. Content-Language
      4. Content-type (Additional restrictions need to be noted)
      5. DPR
      6. Downlink
      7. Save-Data
      8. Viewport-Width
      9. Width
    • The value of the content-type is limited to one of the following:

      1. text/plain
      2. multipart/form-data
      3. application/x-www-form-urlencoded
  • Solution – Back end allows precheck to pass

  • Back-end node-koa

if(ctx.method === 'OPTIONS') {
    ctx.set('Access-Control-Request-Method'.'POST');
    return ctx.body = ' '
}
Copy the code

The back-end agent

  • The back end can answer calls (response-provide services) as well as make calls (send requests)

  • The cross-domain problem is caused by the same origin policy of the browser, so we can request data through the server, not the browser directly, and solve the cross-domain problem

  • That is, the same-origin server acts as a proxy to access other servers: browser -> same-origin server -> non-same-origin server -> same-origin server -> Browser

  • The node native

let data;
const options = {
    protocol: 'http:'.hostname: '127.0.0.1'.port: 3000.path: url.replace(/^\/api/.' '),
    method,
    headers,
}
const req = http.request(options, res= > {
    res.on('data'.chunk= > {
        data += chunk.toString();
        console.log(`BODY: ${chunk}`);
    })
    res.on('end'.() = > {
        res.write(data);
        console.log('complete');
    })
})
req.on('error'.(e) = > {
    console.error(`problem with request: ${e.message}`);
});
req.end();
Copy the code
  • koa-server-http-proxy
app.use(proxy('/api', {
    target: 'http://127.0.0.1:3000'.pathRewrite: {
        '^/api': ' '}}));Copy the code

Proxy mode