美文网首页
跨域问题及方案总结

跨域问题及方案总结

作者: 岳凯 | 来源:发表于2018-12-26 16:11 被阅读0次

先来看下几个概念
跨域问题:浏览器在请求不同域的资源时,会因为同源策略(SOP)的影响而请求不成功,这就是通常所说的跨域问题。
同源策略:来自wiki的解释

In computing, the same-origin policy is an important concept in the web application security model. Under the policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, hostname, and port number.[1][2] This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page's Document Object Model.

对比URL 结果 结果
http://www.example.com/dir/page2.html 同源 相同的协议,主机,端口
http://www.example.com/dir2/other.html 同源 相同的协议,主机,端口
http://username:password@www.example.com/dir2/other.html 同源 相同的协议,主机,端口
http://www.example.com:81/dir/other.html 不同源 相同的协议,主机,端口不同
https://www.example.com/dir/other.html 不同源 协议不同
http://en.example.com/dir/other.html 不同源 不同主机
http://example.com/dir/other.html 不同源 不同主机(需要精确匹配)
http://v2.www.example.com/dir/other.html 不同源 不同主机(需要精确匹配)
http://www.example.com:80/dir/other.html 看情况 端口明确,依赖浏览器实现

常见的跨域解决方式

  1. jsonp

最常用的就是利用$.ajax指定dataType为jsonp,虽然JSONP在跨域ajax请求方面有很强的能力,但是它也有一些缺陷。首先,它没有关于JSONP调用的错误处理,一旦回调函数调用失败,浏览器会以静默失败的方式处理。其次,它只支持GET请求,这是由于该技术本身的特性所决定的。

  1. document.domain

目前,很多大型网站都会使用多个子域名,而浏览器的同源策略对于它们来说就有点过于严格了。如,来自www.a.com想要获取document.a.com中的数据。只要基础域名相同,便可以通过修改document.domain为基础域名的方式来进行通信,但是需要注意的是协议和端口也必须相同。

document.a.com中通过设置

document.domain = 'a.com';

www.a.com中设置:

document.domain = 'a.com';
var iframe = document.createElement('iframe');
iframe.src = 'http://document.a.com';
iframe.style.display = 'none';
document.body.appendChild(iframe);

iframe.onload = function() {
 var targetDocument = iframe.contentDocument || iframe.contentWindow.document;
 //可以操作targetDocument
}

推荐一个使用iframe跨域的库https://github.com/jpillora/xdomain

  1. Nginx反向代理

web2.0时代前后端的分离越来越流行,前后端项目单独部署使得项目更加灵活。举例,前端项目域名为 www.a.com,服务端项目域名为 api.a.com,此时前端请求服务端的时候必然会出现跨域问题,此时可以通过nginx反向代理+域名二级目录的形式解决。

前端设置服务端请求地址为:www.a.com/service/

server {
        listen       80;
        server_name  www.a.com;
        index index.html index.htm index.php;
        root /Data/wwwroot/my-project;
    
        location /service/ {
                rewrite /service/(.*) /$1 break;
                proxy_pass http://api.a.com;
                proxy_set_header Host $proxy_host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }
  }

server {
    listen          80;
    server_name     api.a.com;
    root            /Data/wwwroot/my-api-project/public;
    access_log      /usr/local/var/log/nginx/access.log  main;
    index           index.php index.html index.htm;
    location / {
        #autoindex    on;
        include      /usr/local/etc/nginx/conf.d/php-fpm;
        if (-f $request_filename/index.html){
                rewrite (.*) $1/index.html break;
        }
        if (-f $request_filename/index.htm){
                rewrite (.*) $1/index.htm break;
        }
        if (-f $request_filename/index.php){
                rewrite (.*) $1/index.php;
        }
        if (!-f $request_filename){
                rewrite (.*) /index.php;
        }
    }

}

通过nginx的proxy模块,将/service/下的所有请求转发到 api.a.com 上,通过 www.a.com/service/ 隐藏了真正的server地址

  1. 跨域资源共享CORS(Cross-origin resource sharing)

CORS的核心思想是通过一系列新增的HTTP头信息来实现服务器和客户端之间的通信,
浏览器发送一个带有Orgin字段的HTTP请求头,用来表明请求来源。服务器的Access-Control-Allow-Origin响应头表明该服务器允许哪些源的访问,一旦不匹配,浏览器就会拒绝资源的访问。

浏览器会将CORS请求分为两种:简单请求、非简单请求
简单请求:

  • 请求方法只允许:GET,HEAD,POST
  • 对于请求头字段有严格的要求,一般情况下不会超过以下几个字段: Accept、Accept-Language、Content-Language、Content-Type
  • 当发起POST请求时,只允许Content-Type为application/x-www-form-urlencoded,multipart/form-data,text/plain。

对于前后端分离的项目,服务端和客户端通过RESUful Api通信时,dataType为json的ajax请求显然不是简单请求(Content-Type为application/json),浏览器对于非简单请求会先发送一个类型为options的预请求,options请求的作用是先测试下接口能否返回200,如果不是,则后面真正的get或post请求会丢弃。

针对非简单请求来说,由于每个请求都会发送预请求,这就导致接口数据的返回会有所延迟,时间被加长。所以,在使用CORS的过程中,可以采用一些方案来优化请求,将非简单请求转换成简单请求,从而提高请求的速度。

相关文章

  • 跨域问题及方案总结

    先来看下几个概念跨域问题:浏览器在请求不同域的资源时,会因为同源策略(SOP)的影响而请求不成功,这就是通常所说的...

  • JWT简记

    JSON Web Token(JWT)是目前最流行的跨域认证解决方案。 跨域认证问题及传统解决方案 传统认证流程 ...

  • 跨域问题,解决方案

    跨域问题,解决方案 - Nginx反向代理跨域问题,解决方案 - CORS方案此为原作者的链接:跨域问题,解决之道

  • Webpack 配置 proxy 代理解决跨域问题

    问题 JS跨域及解决方案[https://www.jianshu.com/p/0e9a368ffb74]介绍了跨域...

  • Web前后端跨域问题处理

    跨域问题有前台跨域(iframe间)和后台跨域。 前台跨域的解决方案可以采用跨域文档通讯(Cross domain...

  • 跨域

    跨域资源共享 CORS 详解什么是跨域及怎么解决跨域问题?

  • 跨域解决方案(史上最易懂)

    跨域总结 1.跨域思路 跨域解决方案一般分为两种:前端解决,后端解决 1.1 前端解决方案 通过前端解决的思想就是...

  • 开发环境跨域和生产环境跨域

    开发环境跨域 前后端分离,IP地址不同,请求数据必然导致跨域问题;解决方案:proxy设置 生产环境跨域 解决方案...

  • Js请求跨域问题

    一、请求跨域问题概述 跨域:指的是协议名、端口或者域名不一致的情况都是跨域。 二、跨域问题的解决方案 1、同域代理...

  • ajax跨域请求问题的五种解决方案

    ajax跨域请求问题的五种解决方案 方案一: 使用跨域资源共享代理(corsproxy) 方案二: 使用jsonp...

网友评论

      本文标题:跨域问题及方案总结

      本文链接:https://www.haomeiwen.com/subject/osnhlqtx.html