Ich habe vor kurzem mit dem Programmieren mit dem MEAN-Stack begonnen und implementiere derzeit eine Art soziales Netzwerk. Ich habe das MEAN.io-Framework verwendet, um dies zu tun . Mein Hauptproblem im Moment ist es, den Datei-Upload zum Laufen zu bringen, denn ich möchte die Datei aus dem Formular in den AngularJS-Controller aufnehmen und mit weitergeben Info zu ExpressJS, damit ich endlich alles an MongoDB schicken kann. (Ich baue ein neues Benutzerformular auf).
Ich möchte nicht die Datei selbst in der Datenbank speichern, aber ich möchte einen Link darauf speichern.
Ich habe Dutzende von Seiten mit verschiedenen Suchanfragen bei Google durchsucht, aber ich konnte nichts finden, was ich verstehen oder arbeiten konnte. Seit Stunden stundenlang nach keinem Ergebnis gesucht. Deshalb bin ich hierher gekommen.
Kann mir jemand dabei helfen?
Vielen Dank :)
BEARBEITEN: Vielleicht hilft ein bisschen Code etwas zu verstehen.
Der standardmäßige MEAN.io-Benutzercontroller Angular, den ich als Grundlage verwende, hat folgende Eigenschaften:
$scope.register = function(){
$scope.usernameError = null;
$scope.registerError = null;
$http.post('/register', {
email: $scope.user.email,
password: $scope.user.password,
confirmPassword: $scope.user.confirmPassword,
username: $scope.user.username,
name: $scope.user.fullname
})//... has a bit more code but I cut it because the post is the main thing here.
};
Was ich tun möchte, ist: Empfange eine Datei von einem Formular auf diesen Controller und gib sie zusammen mit E-Mail, Passwort, Namen usw. weiter und kann den Json on expressjs verwenden, der auf der Serverseite sitzt ..__ Das '/ register' ist eine Node-Route, also ein Server-Controller, der den Benutzer (mit dem Benutzerschema) erstellt und an die MongoDB sendet.
Ich habe kürzlich so etwas gemacht. Ich habe angle-file-upload verwendet. Sie möchten auch node-multiparty für Ihren Endpunkt, um die Formulardaten zu parsen. Dann können Sie s3 verwenden, um die Datei nach S3 zu laden.
Hier ist ein Teil meines [bearbeiteten] Codes.
Angular Vorlage
<button>
Upload <input type="file" ng-file-select="onFileSelect($files)">
</button>
Angular Controller
$scope.onFileSelect = function(image) {
$scope.uploadInProgress = true;
$scope.uploadProgress = 0;
if (angular.isArray(image)) {
image = image[0];
}
$scope.upload = $upload.upload({
url: '/api/v1/upload/image',
method: 'POST',
data: {
type: 'profile'
},
file: image
}).progress(function(event) {
$scope.uploadProgress = Math.floor(event.loaded / event.total);
$scope.$apply();
}).success(function(data, status, headers, config) {
AlertService.success('Photo uploaded!');
}).error(function(err) {
$scope.uploadInProgress = false;
AlertService.error('Error uploading file: ' + err.message || err);
});
};
Route
var uuid = require('uuid'); // https://github.com/defunctzombie/node-uuid
var multiparty = require('multiparty'); // https://github.com/andrewrk/node-multiparty
var s3 = require('s3'); // https://github.com/andrewrk/node-s3-client
var s3Client = s3.createClient({
key: '<your_key>',
secret: '<your_secret>',
bucket: '<your_bucket>'
});
module.exports = function(app) {
app.post('/api/v1/upload/image', function(req, res) {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
var file = files.file[0];
var contentType = file.headers['content-type'];
var extension = file.path.substring(file.path.lastIndexOf('.'));
var destPath = '/' + user.id + '/profile' + '/' + uuid.v4() + extension;
var headers = {
'x-amz-acl': 'public-read',
'Content-Length': file.size,
'Content-Type': contentType
};
var uploader = s3Client.upload(file.path, destPath, headers);
uploader.on('error', function(err) {
//TODO handle this
});
uploader.on('end', function(url) {
//TODO do something with the url
console.log('file opened:', url);
});
});
});
}
Ich habe dies von meinem Code aus geändert, daher funktioniert es möglicherweise nicht sofort, aber hoffentlich ist es hilfreich!
Kürzlich wurde der Liste der Pakete auf mean.io ein neues Paket hinzugefügt. Es ist eine Schönheit!
Einfach ausführen:
$ mean install mean-upload
Dadurch wird das Paket im Knotenordner installiert, Sie haben jedoch Zugriff auf die Anweisungen in Ihren Paketen.
http://mean.io/#!/packages/53ccd40e56eac633a3eee335
Fügen Sie in Ihrer Formularansicht Folgendes hinzu:
<div class="form-group">
<label class="control-label">Images</label>
<mean-upload file-dest="'/packages/photos/'" upload-file-callback="uploadFileArticleCallback(file)"></mean-upload>
<br>
<ul class="list-group">
<li ng-repeat="image in article.images" class="list-group-item">
{{image.name}}
<span class="glyphicon glyphicon-remove-circle pull-right" ng-click="deletePhoto(image)"></span>
</li>
</ul>
</div>
Und in deinem Controller:
$scope.uploadFileArticleCallback = function(file) {
if (file.type.indexOf('image') !== -1){
$scope.article.images.Push({
'size': file.size,
'type': file.type,
'name': file.name,
'src': file.src
});
}
else{
$scope.article.files.Push({
'size': file.size,
'type': file.type,
'name': file.name,
'src': file.src
});
}
};
$scope.deletePhoto = function(photo) {
var index = $scope.article.images.indexOf(photo);
$scope.article.images.splice(index, 1);
}
Genießen!
Mean-Upload wurde veraltet und heißt jetzt "Upload". Es wird verwaltet in - https://git.mean.io/orit/upload
Ich weiß, dass dieser Beitrag alt ist. Ich bin darauf gestoßen und @kentcdodds hatte eine Antwort, die mir sehr gut gefallen hat, aber die von ihm verwendeten Bibliotheken sind veraltet und ich konnte sie nicht zum Laufen bringen. Nach einigen Recherchen habe ich eine neuere ähnliche Lösung, die ich teilen möchte.
HTML mit ng-upload
<form >
<div style="margin-bottom: 15px;">
<button type="file" name="file" id="file" ngf-select="uploadFiles($file, $invalidFiles)" accept="image/*" ngf-max-height="1000" ngf-max-size="1MB">Select File</button>
</div>
</form>
INCLUDE ng-upload module
laden Sie es herunter, referenzieren Sie die Dateien und fügen Sie das Modul hinzu
var app = angular.module('app', ['ngFileUpload']);
dadurch erhalten Sie Zugriff auf den Dienst Upload
.
Controller-Code
$scope.uploadFiles = function(file, errFiles) {
$scope.f = file;
$scope.errFile = errFiles && errFiles[0];
if (file) {
file.upload = Upload.upload({
url: 'you-api-endpoint',
data: {file: file}
});
//put promise and event watchers here if wanted
}
};
NODE-API-Code
Der gesamte unten stehende Code befindet sich in einer separaten route
Datei, die required
in meiner Hauptdatei server.js ist.
require('./app/app-routes.js')(app, _);
var fs = require('fs');
var uuid = require('uuid');
var s3 = require('s3fs'); // https://github.com/RiptideElements/s3fs
var s3Impl = new s3('bucketname', {
accessKeyId: '<your access key id>',
secretAccessKey: '< your secret access key >'
});
var multiparty = require('connect-multiparty');
var multipartyMiddleware = multiparty();
module.exports = function(app, _) {
app.use(multipartyMiddleware);
app.post('/your-api-endpoint',function(req, res){
var file = req.files.file; // multiparty is what allows the file to to be accessed in the req
var stream = fs.createReadStream(file.path);
var extension = file.path.substring(file.path.lastIndexOf('.'));
var destPath = '/' + req.user._id + '/avatar/' + uuid.v4() + extension;
var base = 'https://you-bucket-url';
return s3Impl.writeFile(destPath, stream, {ContentType: file.type}).then(function(one){
fs.unlink(file.path);
res.send(base + destPath);
});
});
Ich habe nur versucht, einen einzigartigen Avatar für einen Benutzer hochzuladen. Hoffe das hilft!!