您的位置:

Laravel跨域问题解决方案

一、Nginx跨域解决方案

一些原因会导致我们需要从Laravel应用的URL中实现跨域请求。当前,许多开发者在Laravel和Nginx之间采用一些配置方法,以解决跨域问题。

为了在Nginx中实现跨域访问,我们需要在Laravel应用程序中配置一些参数。请在location / {} 区块内增加如下配置:


location / {
    add_header 'Access-Control-Allow-Origin' "*" always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'X-Requested-With, Authorization, Origin, Content-Type, Accept' always;
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Max-Age' 1728000 always;
        add_header 'Content-Length' 0 always;
        return 204;
    }
}

二、React跨域解决方案

React通常会与Laravel组合使用,因此在跨域问题上,我们读者一些常见的解决方案。

React中可以使用cors库来解决Laravel端跨域访问问题。使用cors库前,需要使用npm安装它。

安装命令:npm install cors –save

使用示例如下:


const express = require('express')
const cors = require('cors')
const app = express()

app.use(cors())

app.get('/example', (req, res) => {
   res.send('Success!')
})

app.listen(3000)

三、Ajax跨域解决方案

1、Ajax跨域JSONP解决方案

JSONP是一种通过动态创建<script>标签来实现跨域访问的方法。使用JSONP存在一定的安全风险,因此在使用时需谨慎。

下面是一个JSONP的示例。我们可以把调用的URL注册到Laravel应用中的routes,然后在JavaScript代码中调用JSONP方法即可:


Route::get('/data',function(){
   $callback=Input::get('callback');
   $data_array = ['name'=>'Jack Ma','age'=>'40'];
   $data = json_encode($data_array);
   return $callback.'('. $data .')';
});

此时,在前端调用Laravel应用数据时,只需在AJAX中使用JSONP方法来实现跨域请求:


function getJsonpData(url){
   return new Promise((resolve, reject) => {
     const script = document.createElement('script');
     script.type = 'text/javascript';
     script.src = `${url}&callback=jsonpCallback`;
     window['jsonpCallback'] = function(data){
       resolve(data);
       document.body.removeChild(script);
     };
     script.onerror = reject;
     document.body.appendChild(script);
   });
}

2、Ajax跨域CORS解决方案

CORS是一种浏览器级别的解决方案,原理为在请求头中添加一些特定的信息。这样即可实现跨域请求。

下面是一个实现Ajax跨域CORS请求的示例:


var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.laravel.com/api/data', true);
xhr.withCredentials = true;
xhr.setRequestHeader('Content-Type','application/json');
xhr.send();
xhr.onreadystatechange = function () {
   if (this.readyState == 4 && this.status == 200) {
      console.log(this.responseText);
   }
};

四、前后端分离跨域问题解决方案

采用前后端分离的方案成为了Web开发的主流,因此跨域问题成为了一个必须解决的问题。这里提供一些解决方案供大家参考。

1、代理转发跨域解决方案

实现前后端分离之后,我们可以通过代理转发的方式来解决跨域请求问题。我们可以在Vue.js中定义一个config/index.js文件,将需要跨域的接口地址和本地代理服务地址配置进去:


module.exports = {
  dev: {
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
}

使用示例如下:


axios.get('/api/data/info').then(function(res){
    console.log(res)
}).catch(function(err){
    console.log(err);
});

2、动态HTML跨域解决方案

在前端使用Vue开发时,如果跨域访问图片或其他动态资源,也常常会使用代理方式来解决问题。下面是使用Vue.js提供的代理方式来访问图片的示例:



   
<script>
  export default {
    data() {
      return {};
    },
    methods: {
      loadImg() {
        axios('/images/logo.png', {responseType: 'blob'}).then(res => {
          let url = window.URL.createObjectURL(res.data);
          this.$refs['logo'][0].src = url;
        });
      }
    },
    created() {
      this.loadImg();
    }
  };
</script>

五、Vue跨域问题的三种解决方案

1、使用自定义代理解决Vue跨域问题

在Vue项目开发过程中,可以通过在本地搭建一个代理服务器来实现跨域请求。下面是实现Vue自定义代理服务器的示例:


devServer: {
    port: 8080,
    proxy: {
        '/api': {
            target: 'http://localhost:3000',
            pathRewrite: {
                '^/api': '/api'
            }
        }
    }
}

2、使用jsonp进行Vue的跨域请求

Vue中也支持使用JSONP进行跨域请求,下面是一段实现Vue的JSONP示例代码:


$http.jsonp('http://example.com/api/data' 
  , {
       jsonpCallback: "successCallback"
}).then(
  function success(response) {
      console.log(response.data);
  });

3、使用Vue的axios库进行跨域请求

Vue中的异步请求可以使用其提供的axios库来实现。下面是使用axios实现Vue跨域请求的示例:


import axios from 'axios'

axios({
    method: 'post',
    url: '/api/data',
    data:{
        message:'Hello World!'
    },

})

六、Springboot跨域问题解决方案

在SpringBoot开发过程中也会遇到跨域问题。下面,我们为大家介绍三种可供选择的跨域解决方案。

1、使用@CrossOrigin注解来解决SpringBoot跨域问题

在SpringBoot开发过程中,我们可以使用Spring提供的@CrossOrigin注解来解决跨域问题。


@CrossOrigin(origins = "http://localhost:8080", maxAge = 3600)
@RequestMapping("/user")
public String getUserList(ModelMap model) {
   return "index";
}

2、基于CORS实现SpringBoot跨域请求

SpringBoot也可以通过CORS协议来实现跨域请求。下面是一段SpringBoot使用CORS实现跨域请求的示例代码:


@Configuration
public class CORSConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedHeaders("*")
            .allowedMethods("*")
            .allowedOrigins("*")
            .allowCredentials(true);
    }
}

3、使用WebMvcConfigurerAdapter实现SpringBoot跨域请求

使用WebMvcConfigurerAdapter也是一种兼容SpringBoot2.x的解决方案。下面是实现SpringBoot使用WebMvcConfigurerAdapter的示例代码:


@Configuration
public class CORSConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://localhost:8880")
                .allowedMethods("GET", "POST")
                .allowedHeaders("*");
    }
}