• 由Credentials引起的cors跨域问题


    一、问题引入

    express搭建服务,接口调用显示跨域,具体如下 

    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'.

    服务端使用express搭建cors配置如下:

    app.all("*", (req, res, next) => {
        // 设置允许跨域的域名,*代表允许任意域名跨域
        res.header("Access-Control-Allow-Origin", "*");
        //允许的header类型
        res.header("Access-Control-Allow-Headers", "content-type");
        //跨域允许的请求方式 
        res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
        if (req.method == 'OPTIONS')
            res.sendStatus(200); //让options尝试请求快速结束
        else
            next();
    })

    但是依旧跨域,后来仔细查看跨域错误信息

    即:设置了 Access-Control-Allow-Credentials 为 true 时,Access-Control-Allow-Origin 不能为*

    显而易见是由于 Credentials 配置,浏览器发起预检请求时返回错误显示跨域

    二、关于Credentials 

    Access-Control-Allow-Credentials,标志是否允许客户端请求携带Credentials(凭证)。Credentials可以是 cookies, authorization headers 或 TLS client certificates.(一般可能携带cookies的情况比较多)。该响应头只能是true或者不设置!

    当作为对预检请求(Option请求)的响应的一部分时,它指示是否可以使用Credentials(凭证)进行实际请求。请注意,若一个对资源的请求带了Credentials,而这个响应头(Access-Control-Allow-Credentials)没有随资源返回,响应就会被浏览器忽视,不会返回到web内容,预检请求也会因此抛出不能通过预检的error。

    三、使用方式

    1.XHR 使用 Credentials

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://example.com/', true); 
    xhr.withCredentials = true;  // 设置withCredentials为true
    xhr.send(null);

    2.JQ 使用 Credentials

    $.ajax({
        type:"POST",
        url: 'http://example.com/',
        data: {},
        xhrFields: {
            withCredentials: true // 设置withCredentials为true
        },
        crossDomain: true,
        dataType: 'json',
        success: successHandler
    });

    3.fetch 使用 Credentials

    fetch控制Credentials的选项有三个:

    请求时携带凭证:credentials: 'include'
    仅在同源时请求时携带凭证:credentials: 'same-origin'(浏览器默认值,在旧版本浏览器,例如safari 11依旧是omit,safari 12已更改)
    不在请求中包含凭证,credentials: 'omit'

    fetch(url, {
        credentials: 'include'
    })

    三、服务端配置

    response响应需添加

    Access-Control-Allow-Credentials: true

    express具体配置如下:

    app.all("*", (req, res, next) => {
        console.log('req.headers.origin', req.headers.origin);
        // 设置允许跨域的域名,*代表允许任意域名跨域
        // res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Origin", req.headers.origin);
        //允许的header类型
        res.header("Access-Control-Allow-Headers", "content-type");
        //跨域允许的请求方式 
        res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
        res.header("Access-Control-Allow-Credentials", true);
        if (req.method == 'OPTIONS')
            res.sendStatus(200); //让options尝试请求快速结束
        else
            next();
    })

    说明:

    Access-Control-Allow-Credentials(可选) – 表示是否允许发送Cookie,只有一个可选值:true(必为小写)。如果不包含cookies,请略去该项,而不是填写false。这一项与 XmlHttpRequest 对象当中的 withCredentials 属性应保持一致,即 withCredentials 为true时该项也为true;withCredentials 为false时,省略该项不写。反之则导致请求失败。

    最后:

    要注意,当设置了 Access-Control-Allow-Credentials 为 true 时,Access-Control-Allow-Origin 不能为*,也是出于一种安全策略,比如:在cookie中存取的是用户的登录信息,又不限制客户端的请求来源,他人获取到cookie以后则可随意发起请求,登录该用户账号,损害用户权益

    参考:https://blog.csdn.net/zSY_snake/article/details/105230125

    更多有关跨域和CORS知识请看本博客其他博文:https://www.cnblogs.com/younghxp/p/14480611.html

  • 相关阅读:
    【转】The final local variable xxx cannot be assigned, since it is defined in an enclosing type
    Android开发UI之手动显示和隐藏软键盘
    ListView使用CursorAdapter增加和删除item
    转:LayoutInflater作用及使用
    Android开发之ContentValues
    Android开发:向下一个activity传递数据,返回数据给上一个activity
    Android开发之bug-No Activity found to handle Intent
    Android学习Service中遇到的问题
    You must supply a layout_width attribute的错误原因及解决办法
    Android:EditText 属性
  • 原文地址:https://www.cnblogs.com/younghxp/p/16203803.html
Copyright © 2020-2023  润新知