NoteZ_技术博客 NoteZ_技术博客
🏠 首页
  • 📚 Web技术
  • 📋 Npm笔记
  • 📑 Markdown
  • 📄 Git笔记
  • 📝 Nginx文档
  • 📓 Linux文档
  • 📖 技术文档
  • 📜 其他文档
  • 🧊 NodeJs
  • 🎡 Express
  • 🔥 Rust
  • 🎉 Koa2
  • 🍃 MongoDB
  • 🐬 MySql
  • 🥦 Oracle
  • 🍁 Python
  • 🍄 JavaScript
  • 🌰 CSS
  • 🧄 HTML
  • 🥑 Canvas
  • 🌽 Nuxt
  • 🍆 React
  • 🥜 Vue
  • 🧅 TypeScript
  • 🌶️ AI
  • 📘 分类
  • 📗 标签
  • 📙 归档
⚜️ 在线编辑 (opens new window)
  • 📁 站点收藏
  • 📦 前端组件库
  • 📊 数据可视化
  • 🌈 开源插件
  • 🎗️ 关于我
  • 🔗 友情链接
GitHub (opens new window)

NoteZ_技术博客

前端界的小学生
🏠 首页
  • 📚 Web技术
  • 📋 Npm笔记
  • 📑 Markdown
  • 📄 Git笔记
  • 📝 Nginx文档
  • 📓 Linux文档
  • 📖 技术文档
  • 📜 其他文档
  • 🧊 NodeJs
  • 🎡 Express
  • 🔥 Rust
  • 🎉 Koa2
  • 🍃 MongoDB
  • 🐬 MySql
  • 🥦 Oracle
  • 🍁 Python
  • 🍄 JavaScript
  • 🌰 CSS
  • 🧄 HTML
  • 🥑 Canvas
  • 🌽 Nuxt
  • 🍆 React
  • 🥜 Vue
  • 🧅 TypeScript
  • 🌶️ AI
  • 📘 分类
  • 📗 标签
  • 📙 归档
⚜️ 在线编辑 (opens new window)
  • 📁 站点收藏
  • 📦 前端组件库
  • 📊 数据可视化
  • 🌈 开源插件
  • 🎗️ 关于我
  • 🔗 友情链接
GitHub (opens new window)
  • JavaScript笔记

    • ajax如何解决跨域问题
      • 什么是跨域
      • 如何解决跨域
        • 1、使用jsonp
        • 2、服务器代理
        • 3、添加响应头
      • 总结
    • async与await语法
    • Axios 文件下载实现进度条功能
    • Axios 的各种请求方式及传参格式总结
    • axios简单使用
    • CommonJS与ES6 Module的导入与导出之间的区别
    • ES6 中 export,export default 和 import 区别及用法
    • Javascript - 如何循环遍历getElementsByClassName返回的所有DOM元素
    • JavaScript 实现 charts 缩放比例尺
    • javaScript 实现将文件流下载文件保存到本地
    • JavaScript 数组对象去重方法
    • JavaScript 生成 uuid
    • JavaScript 解析 get 请求 url 参成对象
    • JavaScript判断字符串中是否包含某个字符串
    • JavaScript判断是否为移动端浏览器
    • JavaScript复制内容到剪贴板的两种常用方法
    • JavaScript实现单词首字母大写的方法总汇
    • JavaScript对时间(time)、日期(date)格式转换
    • JavaScript数组去重方法总结
    • JavaScript数组类型(Array)操作方法汇总
    • JavaScript浅度和深度复制的实现方法
    • js 中的 ES5 面向对象
    • js 中的 ES6 面向对象
    • js 中的 new 命令原理
    • js 实现 iframe通信
    • js 实现将文本复制到粘贴板
    • js 异步操作
    • js 数组转为树形(tree)结构
    • js 文件分片上传
    • js 统计数组中元素的重复次数
    • JS 选中文本输入框的部分文本内容
    • js 面向对象总结
    • Js中的forEach()、map()、$.each()和$.map()之间异同
    • js中的多种数组去重性能对比总结
    • js判断移动端还是pc端
    • JS如何监听div的resize事件
    • js实现格式化JSON数据方法
    • js实现防抖与节流函数
    • Js将滚动条(scrollbar)保持在最底部的方法
    • JS异步编程进化之路
    • JS数组改变元素位置(互换、置顶、上移、下移)
    • js数组的简单使用
    • js文件单位大小转换
    • JS获取和修改url参数
    • JS获取浏览器信息
    • js获取浏览器可视区或页面大小的兼容性总结
    • JS读取本地文本文件(兼容各种浏览器)
    • js随机打乱数组
    • Promise 中的 async 与 await 特点
    • Promise封装请求
    • qs.stringify 的基本用法
    • Web worker 使用方法
    • window.open之浏览器新窗口打开
    • 使用 js 实现保存 .tree 文件到本地
    • 使用 JS 将数字转化成千分位
    • 使用 js 快速计算文件 hash 值
    • 使用 js 进行Base64编码、解码(js-base64)
    • 使用 setTimeout 解决 setInterval 计时器不准的问题
    • 使用js在树形(tree)结构中找到子节点的父级路径
    • 使用JS如何判断远程网络图片地址是否失效
    • 使用js操作浏览器cookie的设置,读取,删除
    • 使用JS解决PC端页面适配方案
    • 使用js递归生成树形结构
    • 使用原生js(input type = file)上传图片(Base64)限制大小、类型判断、像素判断
    • 关于JavaScript 数组的复制解析总结
    • 关于JavaScript数组方法使用总结
    • 内置对象
    • 前端 DOM 总结
    • 前端 js 基础总结
    • 前端使用 jszip 解压 .zip 文件获取 file 格式文件
    • 前端各种事件总结
    • 前端常用的JS(代码片段)小工具方法总结
    • 前端登录界面常用的JS小工具方法总结
    • 十六(16)进制与rgb颜色转换
    • 原生 JavaScript 实现 div 随意拖拽原生 JavaScript 实现 div 随意拖拽
    • 原生 JS 实现页面树形(tree)菜单展示功能
    • 原生js实现 table表格列宽拖拽
    • 原生js获取iframe中dom元素或父级元素
    • 如何使用 file-saver 导出文件到本地?
    • 如何使用js将目录路径list转成tree树结构
    • 实现对localStorage、sessionStorage高级封装
    • 将一维数组按指定长度转为二维数组
    • 将网站设为主页以及加入收藏功能实现方法
    • 总结 3 种 HTML 转 PDF 导出的方案
    • 比typeof运算符更准确的js类型判断
    • 浏览器模型
    • 监听滚动条事件-返回顶部的方法
    • 简析JavaScript中的事件委托问题
    • 返回顶部的通用Js方法
    • 非常实用的Js代码工具片段
    • JS_根据鼠标位置缩放元素、拖拽
    • js_登录验证码绘制
    • JS-以鼠标位置为中心的滑轮缩放-图片
    • js生成目录并实现目录节点跟随滚动高亮
    • 使用js实现标题跳转与复制实现方法
    • 使用原生js动态实现文件的上传功能
    • 使用原生js提取md中的图片信息
    • 3d-force-graph使用方法
    • js 前端(web)浏览器端读取文件目录
    • 原生js监听窗口大小变化
    • JS 中 Promise 用法(简要总结)
  • CSS笔记

  • HTML笔记

  • Canvas笔记

  • Nuxt笔记

  • React笔记

  • Vue笔记

  • TypeScript笔记

  • AI相关笔记

  • 开发文档
  • JavaScript笔记
NoteZ
2024-01-29
目录

ajax如何解决跨域问题

# 什么是跨域

我们所说的跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 JavaScript 施加的安全限制。 在此说明一下,所谓的同源,指的是域名、协议、端口均相等。举例如下:

http://www.abc.com/a/b 调用 http://www.abc.com/d/c(非跨域)
http://www.abc.com/a/b 调用 http://www.def.com/d/c (跨域:域名不一致)
http://www.abc.com:81/a/b 调用 http://www.abc.com:82/d/c (跨域:端口不一致)
http://www.abc.com/a/b 调用 https://www.abc.com/d/c (跨域:协议不同)
1
2
3
4

另外值得注意的是,localhost 和 127.0.0.1 虽然都指向本机,但也属于跨域。在一个 http 请求中,http 头部 Referer 或 Origin 字段标识了当前域名,Host 字段标识了此时请求的域名。所以通过 ajax 请求第三方的数据,就会出现浏览器的跨域问题。

# 如何解决跨域

解决跨域问题,有如下三种方式:

# 1、使用jsonp

  • JSONP 是 JSON with Padding 的略称。它是一个非官方的协议,它允许在服务器端集成 Script tags 返回至客户端,通过 javascript callback 的形式实现跨域访问(这仅仅是 JSONP 简单的实现形式)。

  • jsonp 解决跨域问题的原理是,浏览器的 script 标签是不受同源策略限制的,我们可以在 script 标签中访问任何域名下的资源文件。利用这一特性,用 script 标签从服务器中请求数据,同时服务器返回一个带有方法和数据的 js 代码,请求完成,调用本地的 js 方法,来完成数据的处理。 更多关于 jsonp 的使用方式,可以参考Jsonp和java操作例子 (opens new window),优缺点可以参考JSONP原理优缺点(只能GET不支持POST) (opens new window)。

    以 Jquery 的 ajax 方法为例:

    $.ajax({    
      url:"",    
      dataType:'jsonp',    
      data:'',    
      jsonp:'callback',  
      //传递给请求处理程序或页面的
      //用以获得jsonp回调函数名的参数名(默认为:callback)  
      success:function(result) {    
          //成功的处理  
      },  
      error:function(){  
          //错误处理  
      }   
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    服务端此时返回的不能是普通的 json 字符串,而是一段可以被前端 js 执行的一段js代码。json 与 jsonp 格式的区别:

    //json格式
    {  
        "message":"获取成功",  
        "state":"1",  
        "result":{"name":"工作组1","id":1,"description":"11"}  
    }
    
    1
    2
    3
    4
    5
    6
    //jsonp格式
    callback({  
        "message":"获取成功",  
        "state":"1",  
        "result":{"name":"工作组1","id":1,"description":"11"}  
    })
    
    1
    2
    3
    4
    5
    6

    从格式来看, jsonp 是在 json 的基础上包装了一个方法名,此方法名是前端请求传过来的。

    注意

    jsonp的缺点:

    • JSONP是一种非官方的方法,而且这种方法只支持GET方法,不如POST方法安全。(从实现机制就可明白)。
    • JSONP的实现需要服务器配合,如果是访问的是第三方的服务器,我们没有修改服务器的权限,那么这种方式是不可行的。

# 2、服务器代理

如果服务器A的test01.html页面想访问服务器B的后台action,返回“test”字符串,此时就出现跨域请求,浏览器控制台会出现报错提示,由于跨域是浏览器的同源策略造成的,对于服务器后台不存在该问题,可以在服务器A中添加一个代理action,在该action中完成对服务器B中action数据的请求,然后在返回到test01.html页面。这种方式运用的就是服务器的反向代理技术,控制客户端和服务器的访问都从代理服务器经过,比如用nginx作为服务器代理,在nginx上配置客户端和第三方服务的反向代理,这样就可保证客户端、第三方是同源的了,同一个源,都来自代理服务器。关于 nginx 的反向代理配置,可访问:http://blog.csdn.net/csdn_ds/article/details/58605591

注意

服务器代理的缺点: 开发比较麻烦,对开发环境比较严格,需要在本机上配置代理服务器。

::: info 服务器代理的优点: 完美解决使用jsonp,第三方服务没有修改权限的问题。程序的代码侵入性小,代码级别不需要考虑跨域问题。 :::

# 3、添加响应头

可以在服务端设置 response header 中 Access-Control-Allow-Origin 字段

addHeader(‘Access-Control-Allow-Origin:*’);//允许所有来源访问 
addHeader(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式
1
2

在被请求的 Response Header 中加入如下代码:

// 指定允许其他域名访问   
response.setHeader("Access-Control-Allow-Origin", "*");  
// 响应类型   
response.setHeader("Access-Control-Allow-Methods", "POST");  
// 响应头设置   
response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type");
1
2
3
4
5
6

如果所有请求都想让其他域名的服务通过浏览器ajax请求到,可以通过 Filter 统一设置response header。此处说明一下:只设置 Access-Control-Allow-Origin 属性也是可以的。Access-Control-Allow-Origin:* 表示允许任何域名跨域访问,如果需要指定某域名才允许跨域访问,只需把 Access-Control-Allow-Origin:* 改为 Access-Control-Allow-Origin:允许的域名 例如:

response.setHeader("Access-Control-Allow-Origin","http://www.client.com");
1

注意

缺点: 此种解决跨域方案,需要浏览器支持H5,因为这是HTML5解决跨域的方式,如果产品面向的是PC端,这种方式可能就不是一个好的解决方案,如果面向的是手机端,此方法不为一个简单、粗暴的好方式。 设置*,存在安全隐患。

# 总结

服务代理最好,没有破坏浏览器的安全策略,但这个对开发环境要高一点。设置 response header 的方式,根据具体情况分析,要考虑清楚产品面向的用户。对于 jsonp 这种方式,虽然没有破坏浏览器的安全策略,但只支持 get 方式的请求,有点不能接受,因为 get 传输有参数长度的限制,同时又要考虑传输中文的乱码问题,但如果项目中只是简单的查询、展示,这种方式还是可以考虑的。

#Ajax#JavaScript
上次更新: 2024/11/25, 15:23:15
async与await语法

async与await语法→

最近更新
01
Gitea数据备份与还原
03-10
02
Linux 中使用 rsync 同步文件目录教程
03-10
03
Linux 使用 rsync 互相传输同步文件的简单步骤
03-08
更多文章>
Theme by Vdoing | Copyright © 2019-2025 NoteZ,All rights reserved | 冀ICP备2021027292号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式