记一次前端跨域的问题 - 礼锐的博客

浏览器实现对不同源的网址的资源获取的行为.详见维基百科.这篇文章的起因来源于需要向别的部门进行资源请求, 不在同一个域, 资源请求不到, 等了两天还没解决后便通过node的express来代理请求, 解决了这个问题.

定义(WHAT)

  1. 什么叫不同源(满足下列条件任意一个)
  • 不同的域名(domain)

    • baidu.comgoogle.com 这样名称不相同的就叫不同 domain
  • 不同的端口
    • localhost:8000localhost:3000
    • 如果不写端口号, 根据协议有默认值
      • http: 80
      • https: 443
      • ftp: 21
  • 不同的协议
    • http https ftp ws wss等两两都属于不同地方协议.
  1. 什么叫跨域请求?

利用ajax, image, script等方式, 向不同域请求资源的行为称为跨域请求, 浏览器会与服务端进行沟通, 去判断是否可以进行跨域资源获取, 从而决定请求时成功还是失败.

假设当前域为(可在请求头中查看)
Origin: http://www.foo.com

服务器端设置:
Access-Control-Allow-Origin: http://www.foo.com

如果时公共资源:设置为 *, 即让任意域的请求都可以响应.

  1. 跨域驳回

如果服务器的设置与当前请求的Origin不匹配, 那么浏览器就会驳回这个请求, 无法请求到任何资源, 并会在console中报CORS的错误.所以请注意, 跨域请求并不是没有发请求, 只是浏览器发现跨域后拦截了响应.

为什么(WHY)

小网站可能把所有的资源都放在同一个域下, 但是大型网站内容太多了, 一个服务器或者一个域是放不下了, 而且跨部门的接口调用也很常见, 所以需要使用CORS. 那么又会扯出一个新的问题, 为什么要有同源策略?一句话: 你会同意www.porn.com这个网站访问到你爱存不存的银行账户吗?

这里需要区别一下CSRF(Cross-Site-Request-Forgery)

  • CSRF不需要响应, 只需要你的身份凭证向第三方发送请求.
    大致流程:

    • 登陆支付宝账户
    • 访问a.com
    • a.com向支付宝发送转账到hacker的请求
    • 浏览器发现之前支付宝的cookie信息还未过期, 带着cookie一起发送过去
    • 支付宝发现请求中带有之前已验证的cookie, 认为是本人操作, 同意转账
      可以看到CSRF更多的是在服务端的防御性. 而CORS是着眼客户端的资源获取.他们都属于同源策略下的产物, 但有很大的区别

怎么做(HOW)

实现跨域的具体方式:

最常用的: XMLHTTPRequest

const xhr = new XMLHTTPRequest()
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
        // 判断响应有效性
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            console.log(xhr.responseText)
        } else {
            console.error(‘something error: ‘, xhr.status)
        }
    }
}
xhr.open(‘get‘, ‘www.foo.com‘, true);
xhr.send(null)

open方法参数
- 两个必选参数:
- method: ‘post’, ‘get’
- url: ‘www.foo.com’
- 三个可选参数
- async: true/false 是否异步
- username:string
- password: string

跨域请求的限制
- 无法接收和发送cookies, 那么如果有需要进行用户验证的话可选参数中的username和password, 请避免使用明文, 可加密后传输
- 无法通过setRequestHeader()自定义头部, 要不然服务器要啥origin我传啥origin, 就不会有任何作用了.
- 调用getAllResponseHeaders()获取详细的响应头也只会返回一个空字符串

PreFlighted Request 预发请求

其中有一个细节需要注意的就是浏览器在发现是跨域请求的时候, 是不会先发送这个请求, 而实先发一个 OPTIONS 请求, 这个就是预发请求.将会发送以下头部:

Origin: www.bar.com
Access-Origin-Request-Method: GET
Access-Origin-Request-Header: ABC(可选)

发送请求后, 服务器决定是否接收请求并响应

Access-Control-Allow-Origin: www.bar.com
Access-Control-Allow-Method: GET, POST
Access-Control-Allow-Header: ABC
Access-Control-Max-Age: 3600

这里需要说一下的就是这个Access-Control-Max-Age, 这里规定了多少时间内可以不用再发Option去检测, 而是直接发送请求.所以preflight request的额外请求消耗只在第一次的时候发送.

还有一个特殊的响应头:Access-Control-Allow-Credentials: true/false, 默认情况下跨域请求时部提供cookie, HTTP认证等凭据的. 这里不会影响发送的请求, 只会影响响应, 如果发送的请求携带了验证信息, 但是服务端的响应头里的该字段为false的话浏览器不会将响应交给JavaScript, 即xhr.responseText为空字符串.

注意, 如果将该字段设置为true之后, Access-Controle-Origin-Allow: *是不允许的, 必须指定一个特定的域. 这还是为了安全着想.避免之前说的CSRF

你看, 跨域很简单, 但是需要服务端配合.如果使用express的话可以这样去配置:

// node
const 大专栏  记一次前端跨域的问题 - 礼锐的博客span class="nx">express

时间: 2024-09-30 06:26:08

记一次前端跨域的问题 - 礼锐的博客的相关文章

前端跨域问题的几种解决方案

前端跨域问题 一:同源策略 1.what's this 所谓同源是指,域名,协议,端口相同.当浏览器运行一个JS脚本时会进行同源检测,如果不同源是不能执行的. 2.源继承 来自about:blank,javascript:和data:URLs中的内容,继承了将其载入的文档所指定的源,因为它们的URL本身未指定任何关于自身源的信息. 3.变更源 变更源可以实现基础域相同的不同页面的跨域问题. 如:a.baidu.com/index.html 通过 iframe 引入 b.baidu.com/ind

解决前端跨域请求的几种方式

利用 JSONP 实现跨域调用 说道跨域调用,可能大家首先想到的或者听说过的就是 JSONP 了. 1.1 什么是JSONP JSONP 是 JSON 的一种使用模式,可以解决主流浏览器的跨域数据访问问题.其原理是根据 XmlHttpRequest 对象受到同源策略的影响,而 <script> 标签元素却不受同源策略影响,可以加载跨域服务器上的脚本,网页可以从其他来源动态产生 JSON 资料.用 JSONP 获取的不是 JSON 数据,而是可以直接运行的 JavaScript 语句. 1.2

前端跨域访问

1. JSONP 2. CORS(Cross-origin resource sharing) 2.1 运行模式 2.2 JQuery支持CORS 2.3 与JSONP相比 3. 跨域访问在点评的应用 References 在互联网应用中: 一个页面需要请求多个域名下的web服务端接口 同时一个web服务接口可能会被很多不同域名下的页面请求. 一个web应用如果支持为了支持以上模式而申请多个域名是不合算的,因为域名申请和管理所占用的资源比较大,因此服务端支持跨域就成了一个更合理的解决方案.解决跨

前端跨域几种方式

跨域问题的直接原因是浏览器存在同源策略,浏览器同源指的是:两个页面的协议.端口和主机相同,则两个页面具有相同的源.IE下满足协议.主机相同,就认为是同源. 想象一下,如果没有同源策略,谁都可以修改你站点上的内容,读取你的cookie,后果难以想象 前端跨域的几种方式 修改document.domain document.domain 用来获取当前网页的域名,document.domain可以被赋值 document.domain只能修改成当前域名的主域名或者基础域名,如当前域名是b.360.cn

前端跨域请求原理及实践

前端跨域请求原理及实践 2017-03-03 前端大全 (点击上方公众号,可快速关注) 作者:高鹏 tingandpeng.com/2016/09/05/前端跨域请求原理及实践/ 如有好文章投稿,请点击 → 这里了解详情 一. 跨域请求的含义 浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用. 一般的,只要网站的 协议名protocol. 主机host. 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用.

前端跨域的那些事

这一节,我们来讲一讲,前端跨域的那些事,主要分成这样的几部分来讲解, 一.为什么要跨域? 二.常见的几种跨域与使用场景 2.1 JSONP跨域 2.2 iframe跨域 2.3 window.name 跨域 2.4 document.domain 跨域 2.5 cookie跨域 2.6 postMessage跨域 三.总结 一.为什么要跨域 跨域,通常情况下是说在两个不通过的域名下面无法进行正常的通信,或者说是无法获取其他域名下面的数据,这个主要的原因是,浏览器出于安全问题的考虑,采用了同源策略

前端跨域杂谈

1.前端跨域之表单(post) 项目需求,需要跨域向另一台服务器传送大量值,从ajax角度跨域是get方式,基于此,方案采用构造<form>表单,通过action发送到对方服务器,对方服务器需要做一些配合. 发送方post.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta content="width=device-width,

.net mvc webapi 解决前端跨域问题

跨域问题的原因不解释了,直接设置两步就可以解决前端跨域问题 1.Gloabel.asax文件中 //解决跨域问题 protected void Application_BeginRequest(object sender, EventArgs e) { RegisterRoutes(RouteTable.Routes); if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { HttpContext.Current.Resp

前端跨域方案-跨域请求代理(asp.net handler)

现在技术开发偏向于使用统一的接口处理浏览器或者app的http请求. 大家都知道因为浏览器的同源策略的原因 js直接请求webapi 接口会有一些问题,即使做好服务器端的配置 同样会有不少的 问题  并且会有浏览器的兼容性 而使用jsonp 又需要服务器端对返回数据做相关处理 所以考虑考虑使用代理来解决前端跨域请求的问题. 代理程序走asp.net的一般处理程序,来实现前端js请求的接受然后转发到api站点. 关键点: 1.使用url参数的方式传送api接口的站点路径 http://test.m