0

基本上,API 端的所有代码都存在并且有效。我们可以假设。

另外,我很确定前端 Vue 代码也可以工作。

我遇到的麻烦是,当您按下导出按钮时,我们会收到 CORs 错误。我们根本没有其他 COR 问题。一切都按预期工作。除了这个文件下载。我确实附上了 exportPDF 方法。

Access to XMLHttpRequest at URL from origin https://localhost has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

完整的原始:

Access to XMLHttpRequest at 
'https://example.com/api/v2/messages?Access-Control-Allow-Origin=*&Content-Disposition=form-data&csv_fields[]=id&csv_fields[]=item_id&csv_fields[]=promo_item_id&csv_fields[]=title&csv_fields[]=sent_at&csv_fields[]=sent_total&sort=sent_at%7Cdesc' 
from origin 'https://localhost:3030' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我在请求中做了几次糟糕的尝试,'Access-Control-Allow-Origin': '*'但这无济于事。正如预期的那样。上次我必须使用 API 处理文件时,我创建了一个网络路由来解决它,但这实际上并没有解决问题。它只是绕过 API。可以看到之前开发者的注释“ // need to handle downloading the file.

想法?


async exportCsv() {
  await this.$axios
    .$get(this.getRoute('index'), {
      params: {
        // My Poor attempt next two lines: 
        'Access-Control-Allow-Origin': '*',
        'Content-Disposition': 'form-data',
        csv_fields: this.headerValues,
        sort: this.table.sort[0],
        ...this.filters
      },
    })
    .then((response) => {
      // need to handle downloading the file.
      // currently CORS is not handling the request
      if (response.data.task) {
        this.$store.dispatch('snackbar/show', {
          message: `Export successfully requested. ID: ${response.data.task}`
        })
      }
    })
},

这是我的导出代码,它来自一个名为 Tablify 的方法,我们使用它来格式化代码以返回到 Vue 数据表。

有一个if ($request->has('csv_fields')),它调用这个方法。

use MyCompany\Jobs\ExportCsvJob;

/**
 * Exports the request into a CSV file.
 */
protected function exportCsv(Request $request, Builder $builder)
{
    $fields = collect(Arr::wrap($request->input('csv_fields')));
    $fields = $fields->filter(function ($field) {
        return $this->getTableColumns()->contains($field);
    })->toArray();

    if ($builder->count() <= 1000) {
        return export_csv($fields, $builder->get()); // <-- See func below
    }

    $task = Task::make([
        'name' => 'Exporting CSV',
        'description' => 'Exporting CSV',
        'data' => [
            'download' => '',
        ],
    ]);
    auth()->user()->tasks()->save($task);

    ExportCsvJob::dispatch($fields, $task, $builder);

    return ['task' => $task->id];
}

function export_csv(array $fields, Collection $data, $filename = 'export.csv')
{
    CsvExport::output($fields, $data, $filename);

    if ('testing' !== App::environment()) {
        exit;
    }
}

public static function output(array $fields, Collection $data, $filename = 'export.csv')
{
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename='.$filename);
    header('Access-Control-Allow-Origin *'); <-- just added that. 
    $output = fopen('php://output', 'w');

    fputcsv($output, $fields);
    foreach ($data as $item) {
        fputcsv($output, self::createRowFromItem($fields, $item));
    }

    fclose($output);
}

在我添加该标题后: header('Access-Control-Allow-Origin *'); 我现在得到一个 ERR_HTTP2_PROTOCOL_ERROR

我还没有看到与通过 API 获取文件直接相关的任何其他问题。

在此先感谢堆栈fam!

4

1 回答 1

0

Laravel > 7.x 可以使用您配置的值自动响应 CORS OPTIONS 请求。所有 CORS 设置都可以在您的配置文件中配置,并且 OPTIONS 请求将由默认包含在全局中间件堆栈中cors的中间件自动处理。HandleCors

有关 CORS 和 CORS 标头的更多信息,请参阅有关 CORS 的 MDN Web 文档及其包含在 Laravel > 7 中的laravel-cors包。

如果你有旧版本的 Laravel,你可以在兼容的版本中安装这个包。

于 2020-09-24T16:14:01.900 回答