Angularjs 如何使用CORS上传带有angular的文件

Angularjs 如何使用CORS上传带有angular的文件,angularjs,laravel,laravel-5,restangular,angular1.6,Angularjs,Laravel,Laravel 5,Restangular,Angular1.6,我使用的是restangular 1.51和angular 1.6。我的html看起来像这样 <input type="file" name="file" /> 拉威尔代码: public function upload(Request $request) { $this->validate($request, [ 'file' => 'required', 'type' => 'in:csv,xls,xlsx',

我使用的是restangular 1.51和angular 1.6。我的html看起来像这样

<input type="file" name="file" />
拉威尔代码:

public function upload(Request $request)
{

    $this->validate($request, [
        'file' => 'required',
        'type'  => 'in:csv,xls,xlsx',
        ]);

    $file = $request->file('file');
    var_dump($file);
    return response()->success(['file' => $file]);
}
这里的$file在laravel转储中显示为空数组。这方面的文档非常糟糕。想法

更新 用邮递员就可以了。这是邮递员生成的卷曲:

邮差卷发:

curl -X POST \
  http://127.0.0.1:8000/api/stores/csv \
  -H 'Accept: application/x.toters.v1+json' \
  -H 'Authorization: Bearer ***' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Postman-Token: 4f9d2f3b-551b-aa47-4f65-98c7582f2919' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -F file=@/Users/Shared/Download/bac-383-store-update.csv
curl 'http://127.0.0.1:8000/api/stores/csv' 
-X OPTIONS 
-H 'Access-Control-Request-Method: POST' 
-H 'Origin: http://localhost:3000' 
-H 'Accept-Encoding: gzip, deflate, br' 
-H 'Accept-Language: en-US,en;q=0.9' 
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36' 
-H 'Accept: */*' 
-H 'Connection: keep-alive' 
-H 'Access-Control-Request-Headers: authorization,content-type' 
--compressed


curl 'http://127.0.0.1:8000/api/stores/csv' 
-H 'Origin: http://localhost:3000' 
-H 'Accept-Encoding: gzip, deflate, br' 
-H 'Accept-Language: en-US,en;q=0.9' 
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEwNCwiaXNzIjoiaHR0cDpcL1wvMTkyLjE2OC4wLjIzMjo4MDAwXC9hcGlcL3VzZXJzXC9sb2dpbiIsImlhdCI6MTUxOTk2OTAzNiwiZXhwIjoxNjE0NTc3MDM2LCJuYmYiOjE1MTk5NjkwMzYsImp0aSI6IndHV0UzRjhYQ3hRdDBGOWMifQ.XqySEIprbxtAU-RfhOgtFkScN1nUuuXEwMxCltfjqu8' 
-H 'Content-Type: application/json' 
-H 'Accept: application/x.toters.v1+json' 
-H 'Referer: http://localhost:3000/?local/' 
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36' 
-H 'Connection: keep-alive' 
--data-binary $'------WebKitFormBoundary9ApCHw2ykmLYK2IY\r\nContent-Disposition: form-data; name="file"; filename="bac-383-store-update.csv"\r\nContent-Type: text/csv\r\n\r\n\r\n------WebKitFormBoundary9ApCHw2ykmLYK2IY--\r\n' --compressed
邮递员服务器日志

[2018-03-03 06:35:18] local.INFO: ----------------------------- [] []
[2018-03-03 06:35:18] local.INFO: POST api/stores/csv [] []
[2018-03-03 06:35:18] local.INFO: array (   'file' =>    Illuminate\Http\UploadedFile::__set_state(array(      'test' => false,      'originalName' => 'bac-383-store-update.csv',      'mimeType' => 'text/csv',      'size' => 62,      'error' => 0,   )), ) [] []
[2018-03-03 06:35:18] local.INFO: Status code: 200 [] []
[2018-03-03 06:35:18] local.INFO: User id: 104 [] []
[2018-03-03 06:34:52] local.INFO: ----------------------------- [] []
[2018-03-03 06:34:52] local.INFO: OPTIONS api/stores/csv [] []
[2018-03-03 06:34:52] local.INFO: array ( ) [] []
[2018-03-03 06:34:52] local.INFO: Status code: 200 [] []
[2018-03-03 06:34:52] local.INFO: ----------------------------- [] []
[2018-03-03 06:34:52] local.INFO: POST api/stores/csv [] []
[2018-03-03 06:34:52] local.INFO: array ( ) [] []
[2018-03-03 06:34:52] local.INFO: Status code: 200 [] []
[2018-03-03 06:34:52] local.INFO: User id: 104 [] []

这是restangular生成的旋度

restanglar(两个请求-使用chrome)curl:

curl -X POST \
  http://127.0.0.1:8000/api/stores/csv \
  -H 'Accept: application/x.toters.v1+json' \
  -H 'Authorization: Bearer ***' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Postman-Token: 4f9d2f3b-551b-aa47-4f65-98c7582f2919' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -F file=@/Users/Shared/Download/bac-383-store-update.csv
curl 'http://127.0.0.1:8000/api/stores/csv' 
-X OPTIONS 
-H 'Access-Control-Request-Method: POST' 
-H 'Origin: http://localhost:3000' 
-H 'Accept-Encoding: gzip, deflate, br' 
-H 'Accept-Language: en-US,en;q=0.9' 
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36' 
-H 'Accept: */*' 
-H 'Connection: keep-alive' 
-H 'Access-Control-Request-Headers: authorization,content-type' 
--compressed


curl 'http://127.0.0.1:8000/api/stores/csv' 
-H 'Origin: http://localhost:3000' 
-H 'Accept-Encoding: gzip, deflate, br' 
-H 'Accept-Language: en-US,en;q=0.9' 
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEwNCwiaXNzIjoiaHR0cDpcL1wvMTkyLjE2OC4wLjIzMjo4MDAwXC9hcGlcL3VzZXJzXC9sb2dpbiIsImlhdCI6MTUxOTk2OTAzNiwiZXhwIjoxNjE0NTc3MDM2LCJuYmYiOjE1MTk5NjkwMzYsImp0aSI6IndHV0UzRjhYQ3hRdDBGOWMifQ.XqySEIprbxtAU-RfhOgtFkScN1nUuuXEwMxCltfjqu8' 
-H 'Content-Type: application/json' 
-H 'Accept: application/x.toters.v1+json' 
-H 'Referer: http://localhost:3000/?local/' 
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36' 
-H 'Connection: keep-alive' 
--data-binary $'------WebKitFormBoundary9ApCHw2ykmLYK2IY\r\nContent-Disposition: form-data; name="file"; filename="bac-383-store-update.csv"\r\nContent-Type: text/csv\r\n\r\n\r\n------WebKitFormBoundary9ApCHw2ykmLYK2IY--\r\n' --compressed
restanglar/chrome服务器日志

[2018-03-03 06:35:18] local.INFO: ----------------------------- [] []
[2018-03-03 06:35:18] local.INFO: POST api/stores/csv [] []
[2018-03-03 06:35:18] local.INFO: array (   'file' =>    Illuminate\Http\UploadedFile::__set_state(array(      'test' => false,      'originalName' => 'bac-383-store-update.csv',      'mimeType' => 'text/csv',      'size' => 62,      'error' => 0,   )), ) [] []
[2018-03-03 06:35:18] local.INFO: Status code: 200 [] []
[2018-03-03 06:35:18] local.INFO: User id: 104 [] []
[2018-03-03 06:34:52] local.INFO: ----------------------------- [] []
[2018-03-03 06:34:52] local.INFO: OPTIONS api/stores/csv [] []
[2018-03-03 06:34:52] local.INFO: array ( ) [] []
[2018-03-03 06:34:52] local.INFO: Status code: 200 [] []
[2018-03-03 06:34:52] local.INFO: ----------------------------- [] []
[2018-03-03 06:34:52] local.INFO: POST api/stores/csv [] []
[2018-03-03 06:34:52] local.INFO: array ( ) [] []
[2018-03-03 06:34:52] local.INFO: Status code: 200 [] []
[2018-03-03 06:34:52] local.INFO: User id: 104 [] []
更新2: 比较两个卷发的标题后,我注意到内容类型不同:

邮递员卷曲片段

重新三角形卷曲片段

考虑到使用上述语法,内容类型应该是
application/x-www-form-urlencoded
,这令人震惊:

Restangular.all('用户') .withHttpConfig({transformRequest:angular.identity}) .customPOST(formData,未定义,未定义, {“内容类型”:未定义});这基本上告诉请求使用内容类型:multipart/formdata作为头

所以我写了这个:

    API.all('stores/csv').withHttpConfig({transformRequest: angular.identity})
    .customPOST(formData, undefined, undefined,
      { 'Content-Type': 'application/x-www-form-urlencoded' }).then((response) => {console.log(response);
这使情况有所改善。。现在比较两个卷发:

邮递员

curl -X POST \
  http://127.0.0.1:8000/api/stores/csv \
  -H 'Accept: application/x.toters.v1+json' \
  -H 'Authorization: Bearer ***' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Postman-Token: 4f9d2f3b-551b-aa47-4f65-98c7582f2919' \
  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
  -F file=@/Users/Shared/Download/bac-383-store-update.csv
棱角分明

  curl 'http://127.0.0.1:8000/api/stores/csv' 
  -H 'Origin: http://localhost:3000' 
  -H 'Accept-Encoding: gzip, deflate, br' 
  -H 'Accept-Language: en-US,en;q=0.9' 
  -H 'Authorization: Bearer ***
  -H 'Content-Type: application/x-www-form-urlencoded' 
  -H 'Accept: application/x.toters.v1+json' 
  -H 'Referer: http://localhost:3000/?local/' 
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36' 
  -H 'Connection: keep-alive' 
  --data $'------WebKitFormBoundaryd405EnTxpFJv2GDN\r\nContent-Disposition: form-data; name="file"; filename="bac-383-store-update.csv"\r\nContent-Type: text/csv\r\n\r\n\r\n------WebKitFormBoundaryd405EnTxpFJv2GDN\r\nContent-Disposition: form-data; name="name"\r\n\r\nfile\r\n------WebKitFormBoundaryd405EnTxpFJv2GDN--\r\n' 
  --compressed

因此,我仍然没有发送
-F

我以前没有接触过restangular,但是在Laravel中,当您想要从请求中获取文件时,需要对请求对象使用
file
方法:

$file = $request->file('file');

这应该会给你一个
illumb\Http\UploadedFile

的实例,我没有深入研究过restangular,但在Http级别上,我相信你希望你的
内容类型
头是
多部分/表单数据
,而不是
应用程序/x-www-form-urlencoded

如果您对差异感到好奇,请查看。
由于您正在发送一个文件,
multipart/formdata
就是您想要的


我知道你看到邮递员在做:

-H 'Content-Type: application/x-www-form-urlencoded'
但就在下面几行,它确实:

-H 'content-type: multipart/form-data; boundary...

这没有什么区别我不确定
customPOST
采用什么参数,但是您是否尝试过
customPOST(formData,undefined,undefined,…)
使用
undefined
而不是空字符串,或者
'file'
作为第二个参数?此外,这个例子可能有助于区分大小写内容类型?@abbood:Nothing,HTTP头是不区分大小写的(),那么同一个请求对同一个头有两个不同的值有什么意义呢?HTTP请求可以有重复的头。它对于
缓存控制
Cookie
之类的东西是有意义的,但对于
内容类型
没有太大意义。所以我猜web服务器只是通过使用头的最后一个指定值来处理它。不知道为什么邮递员在这里两次放置相同的标题,也许值得一次公关来修复它:)