I am using uploadify to upload my files and I want to save the files and I want to save path in database, so I am saving the path in session and after the user submit the form. It works on Internet Explorer but on Firefox it's not working because of the change of the session Id.
How to solve this problem?
The uploadify plugin doesn't send cookies so the server cannot identify the session. One possible way to achieve this is to use the scriptData parameter to include the sessionId as request parameter:
<script type="text/javascript">
$(function () {
$('#file').uploadify({
uploader: '<%= Url.Content("~/Scripts/jquery.uploadify-v2.1.4/uploadify.swf") %>',
script: '<%= Url.Action("Index") %>',
folder: '/uploads',
scriptData: { ASPSESSID: '<%= Session.SessionID %>' },
auto: true
});
});
</script>
<% using (Html.BeginForm()) { %>
<input id="file" name="file" type="file" />
<input type="submit" value="Upload" />
<% } %>
This will add the ASPSESSID parameter to the request along with the file. Next we need to reconstruct the session on the server. This could be done in the Application_BeginRequest method in Global.asax:
protected void Application_BeginRequest(object sender, EventArgs e)
{
string sessionParamName = "ASPSESSID";
string sessionCookieName = "ASP.NET_SessionId";
if (HttpContext.Current.Request[sessionParamName] != null)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[sessionCookieName];
if (null == cookie)
{
cookie = new HttpCookie(sessionCookieName);
}
cookie.Value = HttpContext.Current.Request[sessionParamName];
HttpContext.Current.Request.Cookies.Set(cookie);
}
}
and finally the controller action that will receive the upload could use the session:
[HttpPost]
public ActionResult Index(HttpPostedFileBase fileData)
{
// You could use the session here
var foo = Session["foo"] as string;
return View();
}
Related
I've set up a react web application that's currently listing all "Employees" from a mongodb.
I'm now trying to "add" employees to the database through a react frontend form.
I've managed to pass the data from the form to the application but I'm unsure of the process I need to go through to actually get that data solidified into an object and stored in the api.
Please excuse my code, it's disgusting as this is my first week learning react(honestly with little js knowledge, that's another story) and I've just patched together like 20 tutorials....
Here's my Form class:
class Form extends React.Component {
state = {
fullname: '',
}
change = e => {
this.setState({
[e.target.name]: e.target.value
});
}
onSubmit = e => {
e.preventDefault();
this.props.onSubmit(this.state)
this.setState({
fullname: ''
})
}
render() {
return <div>
<form>
<input name="fullname" placeholder="Full Name" value={this.state.fullname} onChange={e => this.change(e)} />
<button onClick={e => this.onSubmit(e)}>Submit</button>
</form>
</div>
}
}
and my Listing(?) class:
class EmployeeList extends React.Component {
constructor(props) {
super(props);
this.state = {employee: []};
this.EmployeeList = this.EmployeeList.bind(this)
this.componentDidMount = this.componentDidMount.bind(this)
}
componentDidMount() {
this.EmployeeList();
}
EmployeeList() {
fetch('/api/employees').then(function(data){
return data.json();
}).then( json => {
this.setState({
employee: json
});
console.log(json);
});
}
onSubmit = fields => {
console.log('app component got: ', fields)
}
render() {
//return a mapped array of employees
const employees = this.state.employee.map((item, i) => {
return <div className="row">
<span className="col-sm-6">{item.fullname}</span>
<span className="col-sm-2" id={item.action1}></span>
<span className="col-sm-2" id={item.action2}></span>
<span className="col-sm-2" id={item.action3}></span>
</div>
});
return <div>
<Form onSubmit={fields => this.onSubmit(fields)}/>
<div className="container">
<div className="row">
<div className="col-sm-6 bg-warning"><h3>Full Name</h3></div>
<div className="col-sm-2 bg-success"><h3>Action 1</h3></div>
<div className="col-sm-2 bg-success"><h3>Action 2</h3></div>
<div className="col-sm-2 bg-success"><h3>Action 3</h3></div>
</div>
</div>
<div id="layout-content" className="layout-content-wrapper">
<div className="panel-list">{ employees }</div>
</div>
</div>
}
}
I've managed to pass the data to the listing app evident by
onSubmit = fields => {
console.log('app component got: ', fields)
}
But how can I go about making a post request to store this data I send into an object on the db? And then also reload the page so that the new list of all employee's is shown?
Thanks so much for your time!
You can use fetch API to make POST request as well. Second parameter is the config object wherein you can pass the required request configurations.
fetch('url', {
method: 'post',
body: JSON.stringify({
name: fields.fullname
})
})
.then(response) {
response.json();
}
.then( json => {
this.setState({
employee: json
});
});
Additional Request Configs which can be used :
method - GET, POST, PUT, DELETE, HEAD
url - URL of the request
headers - associated Headers object
referrer - referrer of the request
mode - cors, no-cors, same-origin
credentials - should cookies go with the request? omit, same-origin
redirect - follow, error, manual
integrity - subresource integrity value
cache - cache mode (default, reload, no-cache)
I'm working my way through a tutorial regarding passport.js and authentication and I'm coming unstuck. I'm just testing the signup function at the moment and my app is freezing. Here's my server file:
var express = require('express'),
app = express(),
mongoose = require('mongoose'),
passport = require('passport'),
flash = require('connect-flash'),
morgan = require('morgan'),
cookieParser = require('cookie-parser'),
bodyParser = require('body-parser'),
session = require('express-session');
// configDB = require('./config/database.js');
mongoose.connect('mongodb://localhost/Auth_practice');
require('./config/passport')(passport); // pass passport for config
// set up express app
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (required for auth)
app.use(bodyParser()); // get information from html forms
app.set('view engine', 'ejs') // set up ejs for templating
// required for passport
app.use(session({secret: 'ilovethetoonandrafa'})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // for persistent login
sessions
app.use(flash());
// routes
require('./app/routes.js')(app, passport); // load our routes
and pass in passport
app.listen(process.env.PORT, process.env.IP, function(){
console.log("Server has started")
});
Here's my user model:
// load the things we need
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
// define schema for our user model
var userSchema = mongoose.Schema({
local :{
email : String,
password : String,
},
facebook :{
id : String,
token : String,
email : String,
name : String
},
twitter :{
id : String,
token : String,
displayName : String,
username : String
},
google :{
id : String,
token : String,
email : String,
name : String
}
});
// method =========================
// generate a hash
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// check if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
My strategy setup:
// config/passport.js
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var User = require('../app/models/user');
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
};
And my route for signup
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/profile', // redirect to the secure profile of the
user
failureRedirect: '/signup', // redirect to signup page if failure
failureFlash: true // allow flash messages
}));
Finally here's the signup form:
<!-- views/signup.ejs -->
<!doctype html>
<html>
<head>
<title>Node Authentication</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> <!-- load bootstrap css -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> <!-- load fontawesome -->
<style>
body { padding-top:80px; }
</style>
</head>
<body>
<div class="container">
<div class="col-sm-6 col-sm-offset-3">
<h1><span class="fa fa-sign-in"></span> Signup</h1>
<!-- show any messages that come back with authentication -->
<% if (message.length > 0) { %>
<div class="alert alert-danger"><%= message %></div>
<% } %>
<!-- LOGIN FORM -->
<form action="/signup" method="post">
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-warning btn-lg">Signup</button>
</form>
<hr>
<p>Already have an account? Login</p>
<p>Or go home.</p>
</div>
</div>
</body>
Can anyone see what's causing the app to freeze?
I am trying to make a range query and show the data in my ejs view
EJS View "historicos.ejs"
<h1>historicos</h1>
<form action="/historicos/buscar">
<input type="text" name='inicio' id='inicio'></li>
<input type="text" name='final' id='final'></li>
<br>
<button type="submit">Buscar</button>
</form>
<% if(typeof his !== 'undefined'){
his.forEach(function(dati){%>
<%= dati.temp %>
<%= dati.hum %>
<%= dati.date %>
<br/>
<%});
}; %>
I am using a controller with 2 methods, 1 for render the page and one to manage the query.
Controller "grafi.js"
var Si = require('../models/sis');
exports.getPagehis = function(req, res) {
if (req.user) return res.redirect('/');
res.render('historicos');
};
exports.getHis= function(req, res, next) {
ini = req.body.inicio;
fin = req.body.final;
console.log(ini)
console.log(fin)
Si.find({"date": {"$gte":ini, "$lt":fin}},function(err, his) {
console.log(his);
if(err) return next(err);
res.render('historicos', {
his:his
});
});
};
and this is my router file
router.get('/historicos', hiController.getPagehis);
router.get('/historicos/buscar', hiController.getHis);
if I write manually ini and fin to make the query(using this format YYYY-MM-DDThh:mm), I mean without the req.body.inicial and req.body.final, it work well but when I request the information from the view I got this fields undifined.
what can i do to solve this?
the problem was form and the request in general adding method="get" in the form and update the controller with:
var Url = require('url');
...
queryparams = Url.parse(req.url,true).query;
ini = queryparams.ini;
fi = queryparams.fi;
... make the query to mongo db
with this code is possible to get the values in the input files passed in the url
I'm using AngularJS v1.2.13 to create a page with a form which will download a user's file on click.
I'm using $sce to enable the injection of the file URL which works fine.
However, the loading of the resource disables the form submit. I'm sure it has to do with the resource load because when I remove the load and hardcode the url it works fine. I've also created a JSFiddle without it and have not been able to reproduce the problem there.
Any ideas on why this is happening and how it can be fixed?
HTML:
<div ng-controller="viewProfileController" data-ng-init="findOne();">
<form method="get" action="{{downloadFileURL}}">
<button type="submit" class="no-button comment-small" >
Download File
</button>
</form>
</div>
Controller:
'use strict';
angular.module('bop.viewProfile').controller('viewProfileController', [
'$scope', 'Users', '$sce', '$routeParams',
function($scope, Users, $sce, $routeParams) {
$scope.downloadFileURL = '';
// Find current user
$scope.findOne = function() {
Users.get({
userId: $routeParams.userId
}, function(user) {
$scope.user = user;
$scope.downloadFileURL = $sce.trustAsResourceUrl($scope.user.file.url);
});
};
}]);
Users Service:
var userServices = angular.module('bop.users', ['ngResource']);
userServices.factory('Users', ['$resource', function($resource) {
return $resource(
'users/:userId',
{ userId: '#_id' },
{ update: { method: 'PUT' } }
);
}]);
Environment: JQuery Form Plugin, jQuery 1.7.1, Zend Framework 1.11.11.
Cannot figure out why jQuery won't parse my json object if I specify an url other than a php file.
The form is as follows:
<form id="imageform" enctype="multipart/form-data">
Upload your image <input type="file" name="photoimg" id="photoimg" />
<input type="submit" id ="button" value="Send" />
</form>
The javascript triggering the ajax request is:
<script type="text/javascript" >
$(document).ready(function() {
var options = {
type: "POST",
url: "<?php $this->baseURL();?>/contact/upload",
dataType: 'json',
success: function(result) {
console.log(result);
},
error: function(ob,errStr) {
console.log(ob);
alert('There was an error processing your request. Please try again. '+errStr);
}
};
$("#imageform").ajaxForm(options);
});
</script>
The code in my zend controller is:
class ContactController extends BaseController {
public function init() {
/* Initialize action controller here */
}
public function indexAction() {
}
public function uploadAction() {
if (isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST") {
$image = $_FILES['photoimg']['tmp_name'];
$im = new imagick($image);
$im->pingImage($image);
$im->readImage($image);
$im->thumbnailImage(75, null);
$im->writeImage('userImages/test/test_thumb.jpg');
$im->destroy();
echo json_encode(array("status" => "success", "message" => "posted successfully"));
}
else
echo json_encode(array("status" => "fail", "message" => "not posted successfully"));
}
}
When I create an upload.php file with the above code, and modify the url from the ajax request to
url: "upload.php",
i don't run into that parsing error, and the json object is properly returned. Any help to figure out what I'm doing wrong would be greatly appreciated! Thanks.
You need either to disable layouts, or using an action helper such as ContextSwitch or AjaxContext (even better).
First option:
$this->_helper->viewRenderer->setNoRender(true);
$this->_helper->layout->disableLayout();
And for the second option, using AjaxContext, you should add in your _init() method:
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('upload', 'json')
->initContext();
This will disable automatically disable layouts and send a json header response.
So, instead of your two json_encode lines, you should write:
$this->status = "success";
$this->message = "posted successfully";
and
$this->status = "fail";
$this->message = "not posted successfully";
In order to set what to send back to the client, you simply have to assign whatever content you want into view variables, and these variables will be automatically convert to json (through Zend_Json).
Also, in order to tell your controller which action should be triggered, you need to add /format/json at the end of your URL in your jQuery script as follow:
url: "<?php $this->baseURL();?>/contact/upload/format/json",
More information about AjaxContext in the manual.
Is the Content-type header being properly set as "application/json" when returning your JSON?