我正在开发一个MEAN堆栈Web应用程序,我想使用ng2-file-upload上传文件。这是我的Angular 2代码。
classroom.component.html
<input type="file" class="form-control" name="single" ng2FileSelect [uploader]="uploader" />
<button type="button" class="btn btn-success btn-s"
(click)="uploader.uploadAll()" [disabled]="!uploader.getNotUploadedItems().length">
<span class="glyphicon glyphicon-upload"></span> Upload all
</button><br />
classroom.component.ts
uploader:FileUploader = new FileUploader({url: "http://localhost:3000/api/material/create-material"});
在server.js中
app.use(cors());
app.use('/api',api);
app.use('/api/material',material);
并在material.js
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1]);
}
});
var upload = multer({ //multer settings
storage: storage
}).single('file');
router.post('/create-material',passport.authenticate('jwt', {session: false}),function (req, res) {
upload(req,res,function(err){
console.log(req.file);
if(err){
res.json({error_code:1,err_desc:err});
return;
}
//res.json({error_code:0,err_desc:null});
});
});
上传文件时出现以下错误
XMLHttpRequest无法加载http://localhost:3000/api/material/create-material。对预检请求的响应未通过访问控制检查:当请求的凭据模式为“包含”时,响应中的“Access-Control-Allow-Origin”标头的值不能是通配符“*”。因此,'http://localhost:4200'原产地不允许进入。 XMLHttpRequest发起的请求的凭据模式由withCredentials属性控制。
这是什么原因?
将以下内容添加到您的nodejs中间件 -
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
CORS支持*,null或精确的协议+域+端口 - > http://www.w3.org/TR/cors/#access-control-allow-origin-response-header
服务器需要使用正则表达式验证原始标头,然后您可以在Access-Control-Allow-Origin响应标头中回显原始值。
这里的问题是你正在运行两个应用程序
因此,当Angular 2应用程序尝试对端口号为“3000”的MEAN堆栈应用程序进行任何调用时,浏览器会抱怨,因为它将被视为跨域ajax。要解决跨域ajax,您必须在MEAN堆栈应用程序中添加以下代码行。
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
如果您真的不喜欢这样做,那么您必须执行以下步骤。
通过执行上述步骤,我们只运行一个位于MEAN堆栈下的应用程序,前端将通过dist文件夹中的角度生成标记提供服务。
ng2-file-upload具有为每个文件指定withcredentials
的选项。
覆盖onAfterAddingFile
并为每个文件设置withCredentials = false
。
例如:this.uploader.onAfterAddingFile = (fileItem:any) => {
fileItem.withCredentials = false;
}
这将解决您的问题。有关更多详细信息: ng2-file-upload/src/file-upload/file-item.class.ts
你的node.js代码将是这样的
var express=require("express");
var multer=require("multer");
var app=express();
var upload=multer({dest:"//destination where you want to upload<folder name>"});
app.post("//routing",upload.single('<variable-name>'),function(req,res){
console.log("File Uploaded");
});
app.listen(//<port-number>);
这里给出的大多数答案都适用于您运行两个应用程序并且需要设置正确的CORS标头以便它们可以通过浏览器进行通信的实现。但是,在您的特定情况下,问题是您使用localhost
进行开发。
问题是Access-Control-Allow-Origin: * doesn't match localhost。鉴于您已根据其他答案提示为您的OPTIONS请求设置了正确的CORS标头,您的预检请求将返回正确的标头,但Chrome不会将localhost
确认为与*
匹配的有效域,并且将无法进行预检检查。
要解决此问题,快速解决方案是将伪域添加到主机文件(如local.development
),然后指向此域而不是localhost
。您现在应该可以使用跨源请求。
快速修复本地主机:
使用Allow-Control-Allow-Origin Chrome扩展程序,然后在列表中添加localhost *
希望这会有所帮助。
并尝试使用FormData进行文件上传。(Angular)
let formData:FormData = new FormData();
formData.append('Document',file);
也许这有助于:
No 'Access-Control-Allow-Origin' - Node / Apache Port Issue
通配符Access-Control-Allow-Origin只是放了一个“*”而不是“http://localhost:8888”来源