应用系统定制开发什么是跨域?跨域解决方法

一、应用系统定制开发为什么会出现问题

       应用系统定制开发出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)应用系统定制开发是一种约定,应用系统定制开发它是浏览器最核心也最应用系统定制开发基本的安全功能,应用系统定制开发如果缺少了同源策略,应用系统定制开发则浏览器的正常功能可应用系统定制开发能都会受到影响。可以说Web应用系统定制开发是构建在同源策略基础之上的,应用系统定制开发浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的。javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port。

二、什么是

1.当一个请求url的三者之间任意一个与当前页面url不同即为跨域。

2.当我们对跨域概念有一定的基础了解时,开始实操一下跨域演示吧!

    2.1目录结构

    2.2前端页面

     public/index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <button id="btn1_get">接口测试1get请求带参数</button>
  11. <button id="btn2_post"> 接口测试2:post-传递普通键值对</button>
  12. <hr/>
  13. <button id="btn3_postJSON">接口测试3:post-传递json</button>
  14. <hr/>
  15. <form id="myform">
  16. <input type="text" name="title">
  17. <input type="file" name="cover">
  18. </form>
  19. <button id="btn4_formdata">接口测试4:post-传递formdata</button>
  20. <hr/>
  21. <script src="./js/axios.js"></script>
  22. <script>
  23. document.getElementById('btn1_get').addEventListener('click',() => {
  24. axios.get('http://localhost:3000/getapi', {params: {a:1,b:2}})
  25. })
  26. var obj = {
  27. "name":"abc",
  28. "address":{
  29. "a":1,
  30. "b":2,
  31. "info":"c"
  32. }
  33. }
  34. document.getElementById('btn2_post').addEventListener('click', () => {
  35. const params = new URLSearchParams();
  36. params.append('param1', 'value1');
  37. params.append('param2', 'value2');
  38. axios.post('http://localhost:3000/post', params, {
  39. headers: {"content-type":"application/x-www-form-urlencoded"}})
  40. })
  41. document.getElementById('btn3_postJSON').addEventListener('click', () => {
  42. axios.post('http://localhost:3000/postJSON', obj)
  43. })
  44. document.getElementById('btn4_formdata').addEventListener('click', () => {
  45. console.log(1)
  46. var fd = new FormData(document.getElementById('myform'));
  47. axios.post('http://localhost:3000/publish',
  48. fd
  49. )
  50. })
  51. </script>
  52. </body>
  53. </html>

 2.3后端

  1. // 实现get接口
  2. const express = require('express')
  3. const app = express();
  4. app.use(express.static('public'))
  5. // 引入bodyParse包
  6. const bodyParser = require('body-parser')
  7. // 使用包. 则在后续的post请求中
  8. // 会自动加入req.body属性,这个属性中就包含了post请求所传入的参数
  9. // 处理普通的键值对格式
  10. // Content-Type: application/x-www-form-urlencoded
  11. app.use(express.urlencoded())
  12. // 处理JSON格式
  13. // Content-Type: application/json;
  14. app.use(express.json())
  15. // 引入multer包
  16. const multer = require('multer');
  17. // 配置一下multer
  18. // 如果本次post请求涉及文件上传,则上传到uploads这个文件夹下
  19. // Content-Type: multipart/form-data;
  20. var upload = multer({ dest: 'uploads/'})
  21. // 实现接口1get类型接口
  22. // 返回所传入的参数,并附上上时间戳
  23. app.get('/getapi',(req,res)=>{
  24. // 通过 req.query快速获取传入的参数
  25. console.log(req.query);
  26. let obj = req.query
  27. obj._t = Date.now();
  28. res.json( obj )
  29. })
  30. // 实现接口2:普通post 键值对
  31. app.post('/post',(req,res)=>{
  32. // 希望在后端收到post传参
  33. console.log(req.body);
  34. let obj = req.body
  35. obj._t = Date.now();
  36. res.json(obj)
  37. })
  38. // 实现接口3:用来JSON格式的数据
  39. // Content-Type: application/json;
  40. app.post('/postJSON',(req,res)=>{
  41. // 希望在后端收到post传参
  42. console.log(req.body);
  43. // res.send('/postJSON')
  44. res.json( req.body )
  45. })
  46. // 实现接口4:接口formDate
  47. app.post('/publish',upload.single('cover'),(req,res)=>{
  48. console.log('publish...')
  49. //upload.single('cover')
  50. // 这里的cover就是在页面中表单元素中的name
  51. // <input type="file" name="cover" />
  52. // 把要上传文件放在指定的目录
  53. console.log(req.file);
  54. // 其它参数,还是在req.body中找
  55. console.log(req.body);
  56. res.json({code:200,msg:'上传成功',info:req.file.path})
  57. })
  58. app.listen(3000,()=>{
  59. console.log('express应用在3000端口启动了');
  60. })

代码报错演示


 三、跨域-错误原因及解决思路

3.1什么原因导致了浏览器报跨域错误

      3.1.1发起的那个页面的地址 和 ajax接口地址 不在同一个域中。

      3.1.2跨域错误:不同源ajax请求====> 报跨域的错误。

      3.1.3浏览器向web服务器发起http请求时 ,如果同时满足以下三个条件时,就会出现跨域问题,从而导致ajax请求失败。

(1)请求响应双方url不同源。

          双方url:发出请求所在的页面 与 所请求的资源的url

          同源是指:协议相同域名相同端口相同 都相同。

以下就是不同源的:

       从http://127.0.0.1:5500/message_front/index.html 请求http://localhost:8080/getmsg

网络中不同源的请求有很多。

(2)请求类型是xhr请求。就是常说的ajax请求。不是请求图片资源,js文件,css文件等

(3)浏览器觉得不安全。跨域问题出现的基本原因是浏览器的同源策略。同源策略是一个重要的安全策略,它限制一个的文档或者它加载的脚本如何能与另一个源的资源进行交互。

注意,错误是发生在浏览器端的。请求是可以正常从浏览器发到服务器端,服务器也可以处理请求,只是返回到浏览器端时出错了。

3.2解决思路

请求响应双方url不同源

    服务器代理

请求是ajax

  • 改发

浏览器觉得不安全 (后端还是能收到请求的)

  • 可以安装一个浏览器插件allow-control-allow-origin 绕过同源策略。
  • 用postman软件测试

3.2.1请求响应双方url不同源

原理

  • script的src属性可以请求外部的js文件,这个请求不是ajax,它没有跨域问题。
  • 借助 script 标签的src请求服务端上的接口。<script src="http://localhost:3000/get"。
  • 服务端的接口返回JavaScript 脚本,并附上要返回的数据。例如:res.end("fn(数据)")。

实现步骤

  • 补充script标签并设置它的src值为接口地址
  • 改造接口返回函数调用表达式,并传入数据
  • 在前端准备相应的函数

注意:

  • script标签中的src会指向一个后端接口的地址。由于script标签并不会导致跨域问题,所以这里的请求是可以正常发送和接收的。
  • 与我们之前理解的src指向某个具体的.js文件不同,我们只需要确保src所指向的地址的返回内容是js代码就行了,而不必要src直接指向某个.js文件。
  • 接口地址中返回的内容将会作为script标签的主体。

 

注意:

  • 后端接口的返回值是一个特殊的字符串: 一个刻意拼写的js函数调用语句。

 图示:

3.2.2改发

       首先前后端需要添加不同的内容,前端加上datastype:json属性,则后端express框架已经提供了一个名为jsonp的方法来处理jsonp请求:原来是res.json,要改成res.jsonp

 3.2.3  CORS

        CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出请求,从而克服了AJAX只能使用的限制。

        CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10(ie8通过XDomainRequest能支持CORS)。

 首先准备一个案例,通过在被请求的路由中设置header头,可以实现跨域。

 那么这样的方法有什么意义呢?

  • 这种方案无需客户端作出任何变化(客户端不用改代码),就当跨域问题不存在一样。
  • 服务端响应的时候添加一个 Access-Control-Allow-Origin 的响应头。

又该如何使用cors

  1. 它是一个npm包,要单独下载使用 npm 包
    npm i cors
  2. 当做express中的中间件,注意代码应该放在顶部

此时也许正在想jsonp vs cors 对比哪个更好呢

jsonp:

  • 不是ajax
  • 只能支持get方式
  • 兼容性好

cors:

  • 前端不需要做额外的修改,就当跨域问题不存在。
  • 是ajax
  • 支持各种方式的请求(post,get....)
  • 浏览器的支持不好(标准浏览器都支持)

持续更新中............

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发