标签:集合 问题 协议 其他 iframe port for ebs code
其实之前就有专门去看过跨域,不过当时使用的很急,简单的看了下就开始使用了,这次看http,就来个系统一点的。
首先什么是跨域。就是访问不属于你这个源的网页(在前端).
源的定义是什么?
协议 + 域名(ip) + 端口
如果这三个完全一样,那就是同源,你不需要跨域,只要有一个不一样,那就属于跨域
跨域这件事是属于浏览器范畴,并不属于http请求,http本身是不阻止这些信息。浏览器处于安全考虑会阻止你访问不属于一个源的资源,会直接阻止你发起请求或者你发起后再阻止。
但是难免会有一些情况需要跨域,比如你要提供api,所以需要在浏览器允许的规则下,实现跨域的操作.
接下来会一个一个测试
简单请求的概念是区别于不简单的请求。
首先请求方式只能是这三种
GET
HEAD
POSTContent-Type 的值仅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器;XMLHttpRequestUpload 对象可以使用XMLHttpRequest.upload 属性访问。
请求中没有使用 ReadableStream 对象。
这是最基本的条件.
其他的条件是请求方需要再header中加入 origin.
然而服务端也得允许
res.setHeader("Access-Control-Allow-Origin", "*");很快可以简单测试一下.
服务端
app.get("/", function (req, res) {
    res.setHeader("Access-Control-Allow-Origin", "http://localhost:5003");
    //add header
    var id = req.query.id * 1;
    req.session.code = id;
    console.log(req.session.code);
    res.send("cors 01 success! " + req.session.code);
});
app.listen(5001, () => {
    console.log(`01 started service`);
});客户端
function ajaxClick() {
    $.ajax({
        url: "http://localhost:5001?id=110",
        type: "GET",
        dataType: "text",
        xhrFields: {
            withCredentials: true
        },
        success: function (data, textStatus) {
            alert(data);
        }
    });
}于是就可以了。如果不加会报错。
Failed to load http://localhost:5001/?id=110: The ‘Access-Control-Allow-Origin‘ header has a value ‘http://localhost:5003‘ that is not equal to the supplied origin. Origin ‘http://localhost:5002‘ is therefore not allowed access.
这就是最简单也最方便的跨域方式. 只要你满足条件就能跨域
如果你需要设置多个
req.headers.origin 做个判断就好了.
res.setHeader("Access-Control-Allow-Origin", "http://localhost:5003");关于跨域带cookie
之前在做单点登录的时候,因为ajax跨域不能带 cookie. 所以很麻烦。
当我看到这个属性
withCredentials: true于是我简单试了一下.
app.get("/", function (req, res) {
    res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
    res.setHeader("Access-Control-Allow-Credentials", true);
    //add header
    var id = req.query.id * 1;
    req.session.code = id;
    console.log("/ :", req.session.code);
    res.send("cors 01 success! " + req.session.code);
});
app.get("/s", function (req, res) {
    res.setHeader("Access-Control-Allow-Origin", req.headers.origin);
    res.setHeader("Access-Control-Allow-Credentials", true);
    let code = req.session.code;
    console.log("s :", code);
    res.send("s :" + code);
});加入了 Access-Control-Allow-Credentials
ajax 也加入相同的 header
结果是可以访问session. 简直不要太舒服.
不过不知道有没有安全性问题,目前正在查这方面的问题。
因为这样的话,很多单点登录的解决方案完全不需要使用认证那一套,但是我看其他网站还是使用认证通知那一套。 所以还是有所顾虑。
IE10+ 才支持这个协议.
之前不太知道这种请求方式,但是见过。
之前再看请求的时候,发现总是发送了两个请求,一个 options,然后再是一个真实请求。
还以为有问题。
其实预检请求相比简单请求就是多了一个请求。
预先发送一个请求,来与服务器确认权限。确认后再继续发送真实请求。
使用了下面任一 HTTP 方法:
1. PUT
2. DELETE
3. CONNECT
4. OPTIONS
5. TRACE
6. PATCH
人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
1. Accept
2. Accept-Language
3. Content-Language
4. Content-Type (but note the additional requirements below)
5. DPR
6. Downlink
7. Save-Data
8. Viewport-Width
9. Width
Content-Type 的值不属于下列之一:
1. application/x-www-form-urlencoded
2. multipart/form-data
3. text/plain
请求中的XMLHttpRequestUpload 对象注册了任意多个事件监听器。
请求中使用了ReadableStream对象。
这就是协议,其实可以简单说不属于简单请求的就是预检请求. 只要你属于以上原则。
于是自己做了一个简单测试
服务端
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", req.headers.origin);
    res.header("Access-Control-Allow-Methods", "OPTIONS");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Access-Control-Allow-Credentials");
    res.header("Access-Control-Allow-Credentials", "true");
    if (req.method == "OPTIONS") {
        res.send(200);
    }
    else {
        next();
    }
});
app.get("/", function (req, res) {
    res.send("跨域成功");
});客户端
$.ajax({
    url: "http://localhost:5003",
    type: "GET",
    dataType: "text",
    contentType: "text/plain",
    headers: {
        "X-PINGOTHER": "pingpong"
    },
    success: function (d) {
        alert(d);
    }
});于是跨域成功.
预检请求 的好处是,能够自己进行验证。当我自定义header以后,就可以自定义去验证。也就可以不光检查来源,还可以做一些加密验证. 只是因为 options 会多一次请求.
简单请求 最简单,但是他不能自定义header,他只能使用来源来做检查。 如果需要非常高安全性的,检查还是比较少。
至于怎么使用就需要看具体情况了。如果只需要简单请求,就不要自定义header等。
原理无非是 script 标签可以直接跨域的。
<script src="http://localhost:5003/jsonp"></script>也就是这样你输入一个地址。 返回一段js,直接调用约定好的方法.
所以这样写便好
前端
<script>
    function test(str) {
        alert(str);
    }
</script>
<script src="http://localhost:5003/jsonp"></script>服务端
app.get("/jsonp", function (req, res) {
    res.type(‘text/javascript‘);
    res.send(‘test("这是来世5003的数据")‘);
});这便是 jsonp 的原理.
但是 jsonp 的问题是。
json 真的很麻烦。fail 你没法去捕获。出了什么问题?404? 还是500? 你无法捕获jsonp出现问题,他说不定可以改变js. 你的其他网站也炸了。 这就是问题。但是他依然有他的应用场景。
还是可以用一波的,毕竟什么都不用设置。直接跨域。
这种方式适用于属于一个一级源的方式。
拿百度来说.
news.baidu.com
map.baidu.com他们都属于 baidu.com. 那就可以相互通信. 仅仅允许这种方式.
需要利用 iframe。双方都设置 domain
document.domain = ‘baidu.com‘;然后 iframe 就可以访问,操作dom.
这个稍显复杂。 原理是通过 hash 来传至.
网站 a 下网页 web1,web2, 网站b. web1
a.web1. 下创建 iframe src=b.web1#11111
b.web1#1111 接受到参数之后
标签:集合 问题 协议 其他 iframe port for ebs code
原文地址:https://www.cnblogs.com/HeyTommy/p/9825670.html