我有带有 vuejs 框架的单页应用程序,我想从服务器获取 excel 文件,但我得到“cors 允许来源与来源不匹配”。在邮递员中我没有问题,我可以下载文件,但在浏览器中我有这个错误
这些是我的代码:
//Vue 组件
<template>
<CRow>
<CCol col="12" xl="12">
<CCard>
<CCardHeader>
گزارش پردازش
</CCardHeader>
<CCardBody>
<CListGroup>
<CRow class="m-bot-10">
<CCol sm="2">
<p class="m-bot-10">
انتخاب تاریخ شروع :
</p>
<date-picker v-model="startDate" format="YYYY-MM-DD"
display-format="jYYYY-jMM-jDD" />
</CCol>
<CCol sm="2">
<p class="m-bot-10">
انتخاب تاریخ پایان :
</p>
<date-picker v-model="endDate" format="YYYY-MM-DD"
display-format="jYYYY-jMM-jDD" />
</CCol>
<CCol sm="2" class="display-flex">
<CButton class="btn btn-success text-white flex-end"
@click="downloadReport" :disabled="linkDisabled">
ذخیره
</CButton>
</CCol>
</CRow>
</CListGroup>
</CCardBody>
</CCard>
</CCol>
<CModal
title="خطا رخ داد"
color="danger"
:show.sync="warningModal">
<CRow v-for="(item, index) in downloadErrors" :key="index">
<CCol sm="12">
<CAlert color="danger" closeButton>
{{ item }}
</CAlert>
</CCol>
</CRow>
<template v-slot:footer>
<button :class="['btn', 'btn-primary']"
@click="warningModal = false">
بستن
</button>
</template>
</CModal>
</CRow>
</template>
<script>
import VuePersianDatetimePicker from 'vue-persian-datetime-picker';
import {baseUrl} from "@/config";
export default {
name: "Operation",
components: {
datePicker: VuePersianDatetimePicker
},
data() {
return {
startDate: new Date().toISOString().split('T')[0],
endDate: new Date().toISOString().split('T')[0],
downloadLink: '',
linkDisabled: false,
warningModal: false,
downloadErrors: [],
}
},
methods: {
downloadReport() {
this.linkDisabled = true;
this.$axios.post('/v1/panel-admin/reports/download_operation_excel', {}, {
params: {
excel: 1,
start_time: this.startDate,
end_time: this.endDate,
},
headers: {
'Accept': `application/json`,
'Authorization': this.$store.getters.access_token,
'Content-Disposition': "attachment; filename=template.xlsx",
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
},
responseType: 'arraybuffer',
})
.then((res) => {
this.linkDisabled = false;
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'template.xlsx');
document.body.appendChild(link);
link.click();
this.linkDisabled = false;
})
.catch((error) => {
console.error(error);
this.warningModal = true;
this.linkDisabled = false;
if (error.response.status == 409) {
this.downloadErrors = [
'بازه زمانی نامعتبر است'
];
}
if (error.response.status == 406) {
this.downloadErrors = [
'بازه زمانی نباید از 2 ماه بیشتر باشد'
];
}
});
}
},
mounted() {
this.$axios.defaults.baseURL = baseUrl;
}
}
</script>
<style scoped>
</style>
//我的laravel控制器方法
public function downloadOperationExcel(Request $request)
{
$rules = [
'start_time' => 'required|date_format:Y-m-d',
'end_time' => 'required|date_format:Y-m-d'
];
$customMessages = [
'required' => 'The :attribute field is required',
'date_format' => 'The :attribute field date format is invalid'
];
$inputData = $request->all();
$validator = Validator::make($inputData, $rules, $customMessages);
if ($validator->fails()) {
return response()->json([
'success' => false,
'messages' => $validator->errors()->all(),
'code' => 400
], 400);
}
$res = $this->getData($request, true);
$data = collect($res['data']);
return Excel::download(new OperationReport($data), $res['file']);
}
我使用fruitcake/laravel-cors包来解决cors问题
这是我的 cors.php 配置:
<?php
return [
/*
|--------------------------------------------------------------------------
| Laravel CORS Options
|--------------------------------------------------------------------------
|
| The allowed_methods and allowed_headers options are case-insensitive.
|
| You don't need to provide both allowed_origins and allowed_origins_patterns.
| If one of the strings passed matches, it is considered a valid origin.
|
| If ['*'] is provided to allowed_methods, allowed_origins or allowed_headers
| all methods / origins / headers are allowed.
|
*/
/*
* You can enable CORS for 1 or multiple paths.
* Example: ['api/*']
*/
'paths' => ['v1/panel-admin/reports/download_operation_excel'],
/*
* Matches the request method. `['*']` allows all methods.
*/
'allowed_methods' => ['*'],
/*
* Matches the request origin. `['*']` allows all origins. Wildcards can be used, eg `*.mydomain.com`
*/
'allowed_origins' => ['*'],
/*
* Patterns that can be used with `preg_match` to match the origin.
*/
'allowed_origins_patterns' => [],
/*
* Sets the Access-Control-Allow-Headers response header. `['*']` allows all headers.
*/
'allowed_headers' => ['*'],
/*
* Sets the Access-Control-Expose-Headers response header with these headers.
*/
'exposed_headers' => ['*'],
/*
* Sets the Access-Control-Max-Age response header when > 0.
*/
'max_age' => 0,
/*
* Sets the Access-Control-Allow-Credentials header.
*/
'supports_credentials' => false,
];
有什么问题吗?
尝试以 JSON 返回 Base64 响应。相反,您使用 Excel::download 您使用 Excel::RAW 并返回 JSON 对象。在 vue 应用程序中,您转换并下载 base64