Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

跨域 #26

Closed
caoxinhui opened this issue May 15, 2020 · 0 comments
Closed

跨域 #26

caoxinhui opened this issue May 15, 2020 · 0 comments
Labels
基础 Something isn't working

Comments

@caoxinhui
Copy link
Owner

caoxinhui commented May 15, 2020

参考文献
软一峰
CORS

JSONP

  • server端
const url = require('url');
require('http').createServer((req, res) => {
    const data = {
        x: 10
    };
    const callback = url.parse(req.url, true).query.callback;
    console.log({callback});
    res.writeHead(200);
    res.end(`${callback}(${JSON.stringify(data)})`)
}).listen(3000, '127.0.0.1');
console.log('启动服务器,监听端口3000');
  • 客户端
<script>
    function jsonpCallback(data) {
        alert('获得x数据:' + data.x)
    }

</script>
<script src="http://127.0.0.1:3000?callback=jsonpCallback"></script>

优点:兼容性好,对浏览器没有依赖性
缺点:

  • 支持Get,不支持 POST 等其他类型的 HTTP 请求
  • 只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面通信
  • 无法捕获 JSONP 请求连接异常,只能通过超时进行处理

CORS

CORS 跨域资源共享(cross-origin resource sharing)

CORS 需要浏览器和服务器同时支持才可以生效。浏览器一旦发现请求是跨域的,就会自动添加一些附加的头信息,有时还会多出一次附加的请求。
因此,CORS通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨域通信。

  • 启动 8080 服务
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname,'public')));
var server = app.listen(8080,function () {
    console.log('启动服务器,监听端口8080');
});
  • 8080 静态页面
<h2>hello</h2>
<script>
    const xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            alert(xhr.responseText)
        }
    };
    xhr.open('GET', 'http://127.0.0.1:3000', true);
    xhr.send()
</script>
  • 跨域请求的服务器
require('http').createServer((req, res) => {
    res.writeHead(200,{
        'Access-Control-Allow-Origin':'http://localhost:8080',
        'Content-Type':'text/html;charset=utf-8'
    });
    res.end('这是你要的数据:1111')
}).listen(3000, '127.0.0.1');
console.log('启动服务器,监听端口3000');

优点:

  • 使用方便,更为安全
  • 支持 POST 请求方式

缺点:

  • 存在兼容性问题

服务器代理

请求后端,让其对该请求代为转发

const url = require('url');
const http = require('http');
const https = require('https');
const server = http.createServer((req, res) => {
    const path = url.parse(req.url).path.slice(1);
    if (path === 'topics') {
        https.get('https://cnodejs.org/api/v1/topics', resp => {
            let data = '';
            resp.on('data', chunk => {
                data += chunk
            });
            resp.on('end', () => {
                res.writeHead(200, {
                    'Content-Type': 'application/json; charset=utf-8'
                });
                res.end(data)
            })
        })
    }
}).listen(3000, '127.0.0.1');
console.log("启动服务");

埋点数据上报

  • AJAX 请求
  • img
    优势:跨域友好,不占用ajax请求,执行无阻塞
  • script

简单请求

@caoxinhui caoxinhui added the 基础 Something isn't working label May 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
基础 Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant