AJAX请求跨域问题

AJAX请求跨域问题

ajax不是js的规范,其全名为Asynchronous JavaScript and XML,意思就是用JavaScript执行异步网络请求。当使用AJAX技术向不同源(协议、域名或端口)的服务器发起请求时,浏览器出于安全考虑会阻止这种请求,这就是所谓的跨域问题。本文将对ajax、同源策略、以及CORS原理进行探讨。

ajax有什么作用

1、ajax的概念与作用

使用传统的form表单时,当点击submit按钮后表单开始提交,这时浏览器会刷新页面,新的页面中会显示成功或失败的信息。若网络出现问题则会显示404页面。也就是说每一次的请求对应一个页面,每次请求都会刷新页面

但在一些情况下需要发送http请求,但是不希望页面刷新,ajax便很好的解决了这个需求。

AJAX(Asynchronous JavaScript and XML)它允许网页在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容。

优点:无需刷新整个页面即可更新内容;只传输必要数据而非整个页面

2、ajax的实现

ajax核心是通过XMLHttpRequest对象Fetch API与服务器进行异步通信

XMLHttpRequest

js 复制代码
// XMLHttpRequest
const xhr = new XMLHttpRequest()
xhr.open('GET', 'https://api.example.com/data', true);
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(JSON.parse(xhr.responseText));
  }
};
xhr.send();

Fetch API

Fetch API配合async写法,代码更加简单。

js 复制代码
const getData = async (url)=> {
    const res = await fetch(url)
    const result = await res.json()
    return result
}
const data = getData('./content.html')

3、跨域问题

  • 同源策略

    假设当前页面URL是 https://example.com/path/to/page.html,那么./content.html 会解析为 https://example.com/path/to/content.html这是因为浏览器的同源策略导致的。同源是指默认情况下JavaScript在发送AJAX请求时,URL的域名必须和当前页面完全一致(只能访问与当前页面同源的资源)。即协议、域名、端口都要相同

    同源策略是浏览器的安全机制,它会限制不同源的DOM访问、不同源的AJAX请求、不同源的Cookie、LocalStorage等访问。但对于标签元素的限制比较小。

    例如:当你登录了 bank.com,并保留了会话 Cookie,然后你访问了一个恶意网站 evil.com,它偷偷向 bank.com 发起 AJAX 请求(跨域请求) 。由于浏览器会自动带上 bank.com 的 Cookie,evil.com 就能窃取你的银行数据,甚至进行转账操作。而同源策略阻止了这种攻击,确保只有 bank.com 自己的页面才能访问 bank.com 的数据。

    若发送请求的URL地址为https://www.sina.com.cn/,这是一个不同源的ajax请求,会报错:

    同源策略的实现逻辑:

    浏览器会先正常发送请求到服务器(请求中携带Origin:https://www.sina.com.cn/ 头)------>服务器会处理请求并返回响应------>浏览器检查请求是否同源若,不同同源浏览器才会拦截响应,不把响应数据交给前端代码

    关键点跨域限制不是阻止请求发送,而是阻止前端JavaScript代码访问响应。服务器始终会收到请求并返回响应,只是浏览器会根据响应头决定是否让前端代码看到这个响应。

  • CORS解决跨域

    COTS是一套允许跨域访问的规则 ,通过 HTTP 头实现。它是通过服务器来告诉浏览器:"我允许某些来源的请求"。也就是说CORS是依赖于服务器的,前端页面是解决不了的。只要服务器明确表示允许,则校验通过,若服务器拒绝或没有明确表示,则不通过。

    实现流程

    • 浏览器 发送跨域请求(如 fetch("https://api.example.com/data")

    • 服务器 返回响应,并带上 CORS 头:

      http 复制代码
      Access-Control-Allow-Origin: https://api.example.com/data
      Access-Control-Allow-Methods: GET, POST
    • 浏览器 检查响应头,如果 Access-Control-Allow-Origin 匹配当前域名或者为***** (代表允许所有访问),就允许前端代码读取响应,否则报跨域错误。

    CORS将请求分为两类:简单请求、预检请求,不是简单请求的就是预检请求

    简单请求

    ​ 请求方法为:GET、HEAD、POST;

    ​ 头部字段满足CORS安全规范(不改动请求头部)

    ​ 请求头的Content-Type为:text/plain、 multipart/form-data、application/x-www-form-urlencoded

    js 复制代码
    // 简单请求
    fetch('https://www.baidu.com/')
    
    // 预检请求 改动了请求头
    fetch('https://www.baidu.com/', {
        method: 'POST',
        headers: {
            name:'s'
        },
    })
    
    // 预检请求
    fetch('https://www.baidu.com/', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json' // 改动了Content-Type
        },
        body: JSON.stringify({
            name: '张三',
            age: 18
        })
    })

    简单请求于预检请求发送方式的区别

    简单请求

    • 浏览器直接发送请求(不带预检 ),自动添加 Origin 头。

    • 服务器返回响应,需包含:

      http 复制代码
      Access-Control-Allow-Origin: * 或当前域名
    • 浏览器检查响应头:若合法则返回数据给前端,若非法则拦截响应(但请求已到达服务器)。

    预检请求prefight

    • 浏览器先发送 OPTIONS 预检请求,携带:

      http 复制代码
      Origin: https://my.com
      Access-Control-Request-Method: PUT      // 声明真实请求方法
      Access-Control-Request-Headers: X-API-Key  // 声明自定义头
    • 服务器需响应预检,返回:

      http 复制代码
      Access-Control-Allow-Origin: 允许的源
      Access-Control-Allow-Methods: GET, POST, PUT  // 允许的方法
      Access-Control-Allow-Headers: X-API-Key       // 允许的头
      Access-Control-Max-Age: 86400                 // 预检缓存时间(秒)
    • 浏览器检查预检响应,若符合要求则 发送真实请求,若不符合则阻止真实请求(控制台报错)

相关推荐
hahala2333几秒前
ESLint 提交前校验技术方案
前端
夕水22 分钟前
ew-vue-component:Vue 3 动态组件渲染解决方案的使用介绍
前端·vue.js
Winwin24 分钟前
js基础-数据类型
javascript
Winwin25 分钟前
哈?Boolean能作为回调函数?
javascript
我麻烦大了25 分钟前
实现一个简单的Vue响应式
前端·vue.js
Shartin29 分钟前
CPT208-Human-Centric Computing: Prototype Design Optimization原型设计优化
开发语言·javascript·原型模式
独立开阀者_FwtCoder33 分钟前
你用 Cursor 写公司的代码安全吗?
前端·javascript·github
dme.41 分钟前
Javascript之DOM操作
开发语言·javascript·爬虫·python·ecmascript
Cacciatore->43 分钟前
React 基本介绍与项目创建
前端·react.js·arcgis
摸鱼仙人~1 小时前
React Ref 指南:原理、实现与实践
前端·javascript·react.js