zoukankan      html  css  js  c++  java
  • 浏览器跨域的细节

    关于什么是跨域,一句话可以说清楚,不同协议,不同子域,不同主域, 不同端口。都可以算成跨域。具体的可以去网上进行搜索。

    那么今天来说一下具体前后端如何跨域的实现代码。

    从前端说起的话

            var headers = new Headers();
            headers.append('Content-Type', 'application/json');
            headers.append('x-node', 'node');
            fetch('http://127.0.0.1:3000/users/login', {
                method: 'POST',
                headers: headers,
                body: JSON.stringify({
                    userName: '鬼剑士',
                    userPwd: '665533',
                })
            });        
    

      比如这段代码跑在localhost:8080的端口上,那么运行以后浏览器会报错如下信息

      

    XMLHttpRequest cannot load http://127.0.0.1:3000/users/login. 
    Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    Origin 'http://127.0.0.1:8080' is therefore not allowed access.

       总而言之就是说你的服务器的响应没有返回 Access-Control-Allow-Origin 这样的响应头,怎么处理呢那么需要去服务器设置跨域的响应头

    设置的代码大致如下:

    以express框架举例

    var cors = require('cors');
    var express = require('express');
    
    var app = express();
    
    app.use(cors());

    然后设置完成以后我们继续请求这个接口,那么这时候的响应头会是这样的

     有些同学可能会问,为什么我们只发送了一个POST请求,但是出来一个options请求?

    这里请看另一篇博文 http://www.cnblogs.com/web-alibaba/p/7583323.html

    接下来就可以愉快的运行了。

    但是有些同学有问题了,你这样的话岂不是请求体里不能带上cookie了,每次都要手动加。多麻烦呀。

    那么解决这个问题的办法是在我们的fetch函数里添加一个选项 credentials, 简单介绍一下credentials。

    这个是为了跨域请求时候控制浏览器的cookie所设计的。参数有三个分别是

    omit:永远不带cookie。

    same-origin: 请求地址和网页的地址在同一个源下就发送cookie,反之不发送。

    include:永远发送。

    那么我们可以在fetch里添加这个选项

    credentials: 'include',然后来看一下结果
    Fetch API cannot load http://127.0.0.1:3000/users/login. 
    Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
    Origin 'http://127.0.0.1:8080' is therefore not allowed access.

    然后愉快的发现又报错了。解释一下错误,当浏览器设置了credentials属性的时候 相应的服务器也需要去设置credentials属性。

    并且 Access-Control-Allow-Origin的域名不能为*,需要指定具体的域名

    那么我们服务端的代码改动成如下

    app.use(cors({
        origin: 'http://127.0.0.1:8080',
        credentials: true,
    }));

    然后看一下cors内部的实现,会发现 credentials为true的时候会返回相应的响应头,浏览器得到以后就会乖乖的不报错了。

     function configureCredentials(options) {
        // 是否带cookies
        if (options.credentials === true) {
          return {
            key: 'Access-Control-Allow-Credentials',
            value: 'true'
          };
        }
        return null;
      }

    然后发现终于成功了,成功的得到了我们想要的json数据

    大概的流程就到这里了。接下来会解析node-cors这个模块。

  • 相关阅读:
    C++学习笔记27,虚函数作品
    HDU
    POJ 2524 Ubiquitous Religions
    HDU-3839-Ancient Messages(DFS)
    thinkphp 删除所有缓存 Rumtime 以及 Html 静态缓存
    [AngularJS] Design Pattern: Simple Mediator
    [Javascript] Add a browser build to an npm module
    [Angular 2] ngrx/store
    [Typescript] Introduction to Generics in Typescript
    [AngularJS] angular-md-table for Angular material design
  • 原文地址:https://www.cnblogs.com/web-alibaba/p/7583311.html
Copyright © 2011-2022 走看看